首页 > 代码库 > XVII Open Cup named after E.V. Pankratiev. Eastern GP, Division 1

XVII Open Cup named after E.V. Pankratiev. Eastern GP, Division 1

A. Count The Ones

$ans=b-c+1$。

#include <stdio.h>using namespace std ;int a  , b , c ;void solve () {	printf ( "%d\n" , 1 + b - c ) ;}int main () {	while ( ~scanf ( "%d%d%d" , &a , &b , &c ) ) solve () ;	return 0 ;}

  

B. Craters

求出凸包,然后枚举凸包上两个点,对第三个点旋转卡壳。因为随机数据凸包期望点数为$O(\sqrt{n})$,故时间复杂度为$O(n\log n)$。

#include<cstdio>#include<cmath>#include<algorithm>#include<set>using namespace std;typedef long long ll;typedef pair<int,int>PI;const int N=200010;int n,m,_,i,j,k,x,y;set<PI>T;ll ans=-1;struct P{  int x,y;  P(){}  P(int _x,int _y){x=_x,y=_y;}  P operator-(P b){return P(x-b.x,y-b.y);}  bool operator<(const P&p)const{    if(x!=p.x)return x<p.x;    return y<p.y;  }  void write(){    printf("%d %d\n",x,y);  }}a[N],b[N<<1],ans0,ans1,ans2;inline ll cross(P a,P b){  return 1LL*a.x*b.y-1LL*a.y*b.x;}inline ll vect(P p,P p1,P p2){  return 1LL*(p1.x-p.x)*(p2.y-p.y)-1LL*(p1.y-p.y)*(p2.x-p.x);}int convexhull(P*p,int n,P*q){  int i,k,m;  sort(p,p+n);  m=0;  for(i=0;i<n;q[m++]=p[i++])while(m>1&&vect(q[m-2],q[m-1],p[i])<=0)m--;  k=m;  for(i=n-2;i>=0;q[m++]=p[i--])while(m>k&&vect(q[m-2],q[m-1],p[i])<=0)m--;  return --m;}inline void work(P a,P b,P c){  ll now=cross(a,b)+cross(b,c)+cross(c,a);  if(now<0)now=-now;  if(now>ans)ans=now,ans0=a,ans1=b,ans2=c;}inline ll area(P a,P b,P c){  ll now=cross(a,b)+cross(b,c)+cross(c,a);  if(now<0)now=-now;  return now;}int main(){  scanf("%d",&n);  if(n<200){    for(i=0;i<n;i++)scanf("%d%d",&a[i].x,&a[i].y);    for(i=0;i<n;i++)for(j=0;j<i;j++)for(k=0;k<j;k++){      work(a[i],a[j],a[k]);    }    ans0.write();    ans1.write();    ans2.write();    return 0;  }  _=n;  n=0;  while(_--){    scanf("%d%d",&x,&y);    if(T.find(PI(x,y))!=T.end())continue;    a[n++]=P(x,y);    T.insert(PI(x,y));  }  m=convexhull(a,n,b);  for(i=0;i<m;i++)b[i+m]=b[i];  for(i=0;i<m;i++){    for(j=i+1,k=j+1;j<i+m;j++){      if(k<=j)k=j+1;      while(k+1<i+m&&area(b[i],b[j],b[k])<=area(b[i],b[j],b[k+1]))k++;      work(b[i],b[j],b[k]);    }  }  ans0.write();  ans1.write();  ans2.write();}

  

C. MSTrikes back!

记录最后$5$个点连通性的最小表示然后DP,注意到边权的周期不会太大,所以可以直接跳过完整的周期。

#include<stdio.h>#include<algorithm>#include<math.h>#include<string.h>#include<string>#include<vector>#include<set>#include<map>#include<queue>#include<time.h>#include<assert.h>#include<iostream>using namespace std;typedef long long LL;typedef pair<int,int>pi;const int Ms=3125;const LL Inf=1LL<<60;const int LIM=100;int n,seed;LL in[LIM+1];LL f[LIM+1][Ms];LL dp[2][Ms];void init(int cs,LL val){	for(int i=0;i<Ms;i++)dp[cs][i]=val;}int g[Ms][(1<<5)+1];void decode(int mask,int *a){	for(int i=0;i<5;i++){		a[i]=mask%5;		mask/=5;	}}void zuixiao(int *a){	int dui[10];	memset(dui,-1,sizeof dui);	int cur=0;	for(int i=0;i<5;i++){		int x=a[i];		if(dui[x]<0){			dui[x]=cur++;		}		a[i]=dui[x];	}}int encode(int *a){	int res=0,tmp=1;	for(int i=0;i<5;i++,tmp=tmp*5){		res+=a[i]*tmp;	}	return res;}bool testt(int *a){	int b[10];	for(int i=0;i<5;i++)b[i]=a[i];	zuixiao(b);	for(int i=0;i<5;i++)if(b[i]!=a[i])return 0;	return 1;}void pre(){	int a[10],b[10];	for(int mask=0;mask<Ms;mask++){		decode(mask,a);		if(!testt(a)){			for(int j=0;j<1<<5;j++)g[mask][j]=-1;			continue;		}		//for(int i=0;i<5;i++)printf("%d ",a[i]);puts(":\n");		for(int j=0;j<1<<5;j++){			for(int i=0;i<5;i++)b[i]=a[i];			b[5]=6;			for(int k=0;k<5;k++){				if(j>>k&1){					for(int t=0;t<5;t++){						if(t==k)continue;						if(b[t]==b[k])b[t]=b[5];					}					b[k]=b[5];				}			}			bool flag=0;			for(int k=1;k<=5;k++)if(b[0]==b[k]){flag=1;break;}			if(!flag)g[mask][j]=-1;			else{				for(int k=0;k<5;k++)b[k]=b[k+1];				zuixiao(b);				//for(int k=0;k<5;k++)printf("%d ",b[k]);puts("");				g[mask][j]=encode(b);			}		}	}}void upd(LL &x,LL y){if(x>y)x=y;}int main(){	pre();	int _;scanf("%d",&_);	while(_--){		scanf("%d%d",&n,&seed);		int cs=0;		init(cs,Inf);		dp[cs][0]=0;		for(int i=2;i<=n&&i<=LIM;i++){			init(cs^1,Inf);			seed=seed*907%2333333;			LL bq[10];			int T=seed;			in[i]=T;			for(int j=0;j<5;j++){				if(i-(5-j)<1)bq[j]=Inf;				else {					seed=seed*907%2333333;					bq[j]=seed^T;				}			}			for(int mask=0;mask<Ms;mask++){				LL w=dp[cs][mask];				if(w==Inf)continue;				for(int j=0;j<1<<5;j++){					if(g[mask][j]<0)continue;					bool flag=1;					for(int k=0;k<5;k++)if((j>>k&1)&&(bq[k]==Inf)){						flag=0;continue;					}					if(!flag)continue;					LL nw=w;					for(int k=0;k<5;k++){						if(j>>k&1)nw+=bq[k];					}					upd(dp[cs^1][g[mask][j]],nw);				}			}			cs^=1;			for(int j=0;j<Ms;j++)f[i][j]=dp[cs][j];		}		if(n<=LIM)printf("%lld\n",dp[cs][0]);		else{			LL pace,pacew;			for(int i=LIM-1;;i--)if(in[i]==in[LIM]){				pace=LIM-i;				break;			}			int st=(n-LIM)/pace*pace+LIM;			//printf("st=%d\n",st);			for(int i=0;i<Ms;i++){				dp[cs][i]=f[LIM][i]+1LL*(n-LIM)/pace*(f[LIM][i]-f[LIM-pace][i]);			}			for(int i=st+1;i<=n;i++){				init(cs^1,Inf);				seed=seed*907%2333333;				LL bq[10];				int T=seed;				for(int j=0;j<5;j++){					if(i-(5-j)<1)bq[j]=Inf;					else {						seed=seed*907%2333333;						bq[j]=seed^T;					}				}				for(int mask=0;mask<Ms;mask++){					LL w=dp[cs][mask];					if(w==Inf)continue;					for(int j=0;j<1<<5;j++){						if(g[mask][j]<0)continue;						bool flag=1;						for(int k=0;k<5;k++)if((j>>k&1)&&(bq[k]==Inf)){							flag=0;continue;						}						if(!flag)continue;						LL nw=w;						for(int k=0;k<5;k++){							if(j>>k&1)nw+=bq[k];						}						upd(dp[cs^1][g[mask][j]],nw);					}				}				cs^=1;			}			printf("%lld\n",dp[cs][0]);		}	}		return 0;}

  

D. Skyscrapers

首先用set维护所有已经被摧毁的建筑。然后用线段树维护区间内最容易被向左/向右的冲击波击毁的建筑即可。时间复杂度$O(n\log n)$。

#include<cstdio>#include<set>#include<algorithm>using namespace std;const int N=100010,M=262150;int n,m,i,x,ans,f[N],g[N];set<int>T;int vl[M],vr[M],pos[N],p;inline int mergel(int x,int y){  if(!x||!y)return x+y;  return f[x]>f[y]?x:y;}inline int merger(int x,int y){  if(!x||!y)return x+y;  return g[x]<g[y]?x:y;}void build(int x,int a,int b){  if(a==b){    pos[a]=x;    vl[x]=vr[x]=a;    return;  }  int mid=(a+b)>>1;  build(x<<1,a,mid);  build(x<<1|1,mid+1,b);  vl[x]=mergel(vl[x<<1],vl[x<<1|1]);  vr[x]=merger(vr[x<<1],vr[x<<1|1]);}void askl(int x,int a,int b,int c,int d){  if(c<=a&&b<=d){    p=mergel(p,vl[x]);    return;  }  int mid=(a+b)>>1;  if(c<=mid)askl(x<<1,a,mid,c,d);  if(d>mid)askl(x<<1|1,mid+1,b,c,d);}void askr(int x,int a,int b,int c,int d){  if(c<=a&&b<=d){    p=merger(p,vr[x]);    return;  }  int mid=(a+b)>>1;  if(c<=mid)askr(x<<1,a,mid,c,d);  if(d>mid)askr(x<<1|1,mid+1,b,c,d);}inline void kill(int x){  ans++;  T.insert(x);  x=pos[x];  vl[x]=vr[x]=0;  for(x>>=1;x;x>>=1){    vl[x]=mergel(vl[x<<1],vl[x<<1|1]);    vr[x]=merger(vr[x<<1],vr[x<<1|1]);  }}inline void workl(int l,int r,int t){  if(l>r)return;  while(1){    p=0;    askl(1,1,n,l,r);    if(!p)return;    if(f[p]<t)return;    kill(p);  }}inline void workr(int l,int r,int t){  if(l>r)return;  while(1){    p=0;    askr(1,1,n,l,r);    if(!p)return;    if(g[p]>t)return;    kill(p);  }}int main(){  scanf("%d",&n);  for(i=1;i<=n;i++)scanf("%d",&x),f[i]=i-x,g[i]=i+x;  T.insert(0);  T.insert(n+1);  build(1,1,n);  scanf("%d",&m);  while(m--){    scanf("%d",&x);    ans=0;    kill(x);    set<int>::iterator j=T.find(x),k;    k=j;    j--;k++;    workl(*j+1,x-1,f[x]);    workr(x+1,*k-1,g[x]);    printf("%d\n",ans);  }/*left:a[x]-a[y]>=x-yy-a[y]>=x-a[x]get max(y-a[y])right:a[x]-a[y]>=y-xy+a[y]<=x+a[x]get min(y+a[y])*/}

  

E. Blackboard

按题意模拟即可。

#include<stdio.h>#include<algorithm>#include<math.h>#include<string.h>#include<string>#include<vector>#include<set>#include<map>#include<queue>#include<time.h>#include<assert.h>#include<iostream>using namespace std;typedef long long LL;typedef pair<int,int>pi;int n,ty;int a[103][103];void rev(){	for(int i=1;i<=n;i++){		for(int j=i;j<=n;j++){			swap(a[i][j],a[j][i]);		}	}}void solve1(){	int cur=1;	for(int i=1;i<=n;i++){		if(i&1){			for(int j=1;j<=n;j++){				a[i][j]=cur++;			}		}		else{			for(int j=n;j>=1;j--){				a[i][j]=cur++;			}		}	}}bool isok(int x,int y){	return x>=1&&x<=n&&y>=1&&y<=n&&a[x][y]==0;}int di[4][2]={{0,1},{1,0},{0,-1},{-1,0}};void solve2(){	int d=0;	int sx=1,sy=1;	memset(a,0,sizeof a);	int cur=1;	for(int it=1;it<=n*n;it++){		a[sx][sy]=cur++;		int nx=sx+di[d][0],ny=sy+di[d][1];		if(it==n*n)break;		while(!isok(nx,ny)){			d++;			d%=4;			nx=sx+di[d][0],ny=sy+di[d][1];		}		sx=nx,sy=ny;	}}int main(){	while(scanf("%d%d",&n,&ty)!=EOF){		if(ty==1||ty==2)solve1();		if(ty==3||ty==4)solve2();		if(ty==2||ty==4)rev();		for(int i=1;i<=n;i++){			for(int j=1;j<=n;j++){				printf("%d%c",a[i][j],j==n?‘\n‘:‘ ‘);			}		}	}	return 0;}

  

F. Buddy Numbers

若质数太多那么显然无解,对于小数据爆搜即可。

#include <bits/stdc++.h>using namespace std ;int a[1000] , n ;void solve () {	if ( n == 1 ) {		printf ( "1\n" ) ;		return ;	}	if ( n == 2 ) {		printf ( "1 2\n" ) ;		return ;	}	if ( n == 3 ) {		printf ( "2 1 3\n" ) ;		return ;	}	if ( n == 4 ) {		printf ( "2 4 1 3\n" ) ;		return ;	}	if ( n == 6 ) {		printf ( "3 6 2 4 1 5\n" ) ;		return ;	}	printf ( "-1\n" ) ;		}int main () {	while ( ~scanf ( "%d" , &n ) ) solve () ;	return 0 ;}

  

G. Gmoogle

按题意模拟即可。注意首尾空格的处理以及文末没有标点符号的情况的处理。

#include<stdio.h>#include<algorithm>#include<math.h>#include<string.h>#include<string>#include<vector>#include<set>#include<map>#include<queue>#include<time.h>#include<assert.h>#include<sstream>#include<iostream>using namespace std;typedef long long LL;typedef pair<int,int>pi;string s;vector<string>jz;int can[1020];int isend(int loc){	if(s[loc]!=‘.‘&&s[loc]!=‘!‘&&s[loc]!=‘?‘)return 0;	if(s[loc]==‘.‘){		int j=loc+1;		while(j<s.size()&&s[j]==‘ ‘)j++;		if(j<s.size()&&s[j]>=‘a‘&&s[j]<=‘z‘)return 0;	}	return 1;}void cg(char &c){if(c>=‘A‘&&c<=‘Z‘)c=c-‘A‘+‘a‘;}bool cmp(char c1,char c2){	cg(c1),cg(c2);	if(c1==c2)return 1;	return 0;}bool ok(string &wb,string& in){	for(int i=0;i+in.size()<=wb.size();i++)if(isalpha(wb[i])){		bool flag=1;		if(i&&isalpha(wb[i-1]))continue;//		int j=i+in.size();		if(j<wb.size()&&isalpha(wb[j]))continue;//		//while ( j < wb.size () && wb[j] == ‘ ‘ ) ++ j ;		//if(j<wb.size()-1&&wb[j]==‘.‘)continue;		for(int j=0;j<in.size();j++){			if(cmp(wb[i+j],in[j])!=1){flag=0;break;}		}		if(flag)return 1;	}	return 0;}bool zhu(char x){  if(x>=‘a‘&&x<=‘z‘)return 1;  if(x>=‘A‘&&x<=‘Z‘)return 1;  if(x==‘ ‘)return 1;  if(x>=‘0‘&&x<=‘9‘)return 1;  if(x==‘.‘||x==‘?‘||x==‘!‘)return 1;  return 0;}void fix ( string& s ) {	while ( !zhu(s[s.size () - 1]) ) s.pop_back () ;}int main(){	getline(cin,s);	fix ( s ) ;	int k = 0 ;	for(int l=0;l<s.size();){		while(l<s.size()&&s[l]==‘ ‘)l++;		if(l>=s.size())break;		//if ( s[l] == ‘.‘ /*|| s[l] == ‘?‘ || s[k] == ‘!‘*/ ) while ( 1 ) ;		int r=l;		string tmp="";		while(r<s.size()&&!isend(r))tmp.push_back(s[r++]);		if ( r < s.size () ) tmp.push_back(s[r++]);		while(tmp[tmp.size()-1]==‘ ‘)tmp.pop_back();		//printf ( "%d\n" , ( int ) tmp.size () ) ;		jz.push_back(tmp);		l=r;	}	/*	cout<<"OUTPUT"<<endl;	for(int i=0;i<jz.size();i++)cout<<jz[i]<<endl;	*/	int q;scanf("%d",&q);	string rub;	getline(cin,rub);	while(q--){		string que;		getline(cin,que);		fix ( que ) ;		for(int i=0;i<jz.size();i++)can[i]=1;		stringstream ss(que);		string tmp;		while(ss>>tmp){			fix ( tmp ) ;			for(int i=0;i<jz.size();i++){				if(!ok(jz[i],tmp))can[i]=0;			}		}		int i=0,j=que.size()-1;		while(que[i]==‘ ‘)i++;		while(que[j]==‘ ‘)j--;		cout<<"Search results for \"";		for(int it=i;it<=j;it++)printf("%c",que[it]);		cout<<"\":\n";		for(int i=0;i<jz.size();i++)if(can[i]){			cout<<"- \""<<jz[i]<<"\"\n";		}	}	return 0;}

  

H. Generator

线性筛求出每个数的最小质因子即可。

#include<stdio.h>#include<algorithm>#include<math.h>#include<string.h>#include<string>#include<vector>#include<set>#include<map>#include<queue>#include<time.h>#include<assert.h>#include<iostream>using namespace std;typedef long long LL;typedef pair<int,int>pi;LL n;LL sum[10000020];int tot[10000020];bool isp[10000200];vector<int>pri;const int Maxn=10000010;int getsq(int x){	int tmp=sqrt(x+0.5);	while(tmp*tmp<x)tmp++;	while(tmp*tmp>x)tmp--;	return tmp-1;}void pre(){	for(int i=2;i<Maxn;i++){		if(!isp[i])pri.push_back(i),sum[i]=getsq(i);		for(int j=0;j<pri.size();j++){			int x=pri[j];			if(x*i>=Maxn)break;			sum[x*i]=x-1;			isp[i*x]=1;			if(i%x==0)break;		}	}	//for(int i=2;i<=10;i++)printf("%lld ",sum[i]);puts("");	for(int i=2;i<Maxn;i++)sum[i]+=sum[i-1];	for(int i=2;i<Maxn;i++)tot[i]=tot[i-1]+(!isp[i]);}int main(){	pre();	int _;scanf("%d",&_);	while(_--){		scanf("%lld",&n);		LL ans=sum[n];		if(ans==0)printf("0/1\n");		else{			LL gc=__gcd((LL)tot[n],ans);			printf("%lld/%lld\n",ans/gc,tot[n]/gc);		}			}	return 0;}

  

I. Addition

维护二进制字典树即可。

#include <bits/stdc++.h>using namespace std ;typedef long long LL ;const int MAXN = 100005 ;int nxt[MAXN][2] ;int cnt[MAXN] ;char s[MAXN] , s1[MAXN] ;int cur , root ;int n , m ;int newnode () {	++ cur ;	nxt[cur][0] = nxt[cur][1] = 0 ;	cnt[cur] = 0 ;	return cur ;}void insert ( char s[] ) {	int now = root ;	for ( int i = 0 ; i < m ; ++ i ) {		int x = s[i] ;		if ( !nxt[now][x] ) nxt[now][x] = newnode () ;		now = nxt[now][x] ;		cnt[now] ++ ;	}}int query ( char s[] ) {	int now = root , ans = 0 ;	for ( int i = 0 ; i < m ; ++ i ) {		int x = s[i] ;		if ( !x ) ans += cnt[nxt[now][1]] ;		now = nxt[now][x] ;	}	return ans ;}void solve () {	cur = 0 ;	root = newnode () ;	for ( int i = 1 ; i <= n ; ++ i ) {		scanf ( "%s" , s ) ;		for ( int j = 0 ; j < m ; ++ j ) {			s[j] -= ‘0‘ ;			s1[j] = 1 ^ s[j] ;		}		int ans = query ( s1 ) ;		insert ( s ) ;		printf ( "%d\n" , ans ) ;		fflush ( stdout ) ;	}}int main () {	scanf ( "%d%d" , &n , &m ) ;	solve () ;	return 0 ;}

  

J. Votter and Paul De Mort

留坑。

 

K. GCD on the segments

考虑枚举左端点$i$,则随着右端点的右移,一共只有$O(\log n)$种不同的$\gcd$取值。所以首先通过ST表+二分查找预处理出$O(n\log n)$个四元组$(x,i,l,r)$,表示左端点为$i$,右端点取值范围在$[l,r]$内,且这一段的$\gcd$都为$x$。

将四元组按照$x$为第一关键字,$i$为第二关键字排序,对于相同的$x$一起处理。

当$x$相同时,显然所有的$i$互不相同。设$f[i]$为恰好以位置$i$为结尾的最优解,则对于一个四元组$(x,i,l,r)$,能更新它的最优解为区间$[1,i-1]$的最优值$+1$,然后用它更新区间$[l,r]$的$f[]$。用支持打标记的线段树维护即可。时间复杂度$O(n\log^2n)$。

#include<cstdio>#include<cstdlib>#include<algorithm>using namespace std;const int N=100010,K=17,P=1000000007,M=262145;int T,n,m,i,j,x,y,l,r,mid,Log[N],val,f[K][N];struct PI{  int x,i,l,r;  PI(){}  PI(int _x,int _i,int _l,int _r){x=_x,i=_i,l=_l,r=_r;}}a[3000000];inline bool cmp(PI a,PI b){return a.x==b.x?a.i<b.i:a.x<b.x;}struct Num{  int x,y;  Num(){x=y=0;}  Num(int _x,int _y){x=_x,y=_y;}  inline Num operator+(Num b){    if(x<b.x)return b;    if(x>b.x)return Num(x,y);    return Num(x,(y+b.y)%P);  }  inline Num operator+(int _x){return Num(x+_x,y);}  inline Num operator-(int b){return Num(x,(long long)y*b%P);}  inline void operator+=(Num b){*this=*this+b;}}tmp,v[M],tag[M],ans;int pos[M];inline void read(int&a){char c;while(!(((c=getchar())>=‘0‘)&&(c<=‘9‘)));a=c-‘0‘;while(((c=getchar())>=‘0‘)&&(c<=‘9‘))(a*=10LL)+=c-‘0‘;}inline int askgcd(int y){int k=Log[y-i+1];return __gcd(f[k][i],f[k][y-(1<<k)+1]);}inline void clean(int x){  if(pos[x]<T)pos[x]=T,v[x]=tag[x]=Num();}inline void tag1(int x,Num y){  clean(x);  v[x]+=y;  tag[x]+=y;}inline void pb(int x){  if(tag[x].x){    tag1(x<<1,tag[x]);    tag1(x<<1|1,tag[x]);    tag[x]=Num();  }}inline void up(int x){  clean(x<<1),clean(x<<1|1);  v[x]=v[x<<1]+v[x<<1|1];}void change(int x,int a,int b,int c,int d){  clean(x);  if(c<=a&&b<=d){tag1(x,tmp);return;}  pb(x);  int mid=(a+b)>>1;  if(c<=mid)change(x<<1,a,mid,c,d);  if(d>mid)change(x<<1|1,mid+1,b,c,d);  up(x);}void ask(int x,int a,int b,int c,int d){  clean(x);  if(c<=a&&b<=d){tmp+=v[x];return;}  pb(x);  int mid=(a+b)>>1;  if(c<=mid)ask(x<<1,a,mid,c,d);  if(d>mid)ask(x<<1|1,mid+1,b,c,d);  up(x);}int main(){  for(i=2;i<=100000;i++)Log[i]=Log[i>>1]+1;  while(~scanf("%d",&n)){    m=0;    ans=Num();    for(i=1;i<=n;i++)read(f[0][i]);    int flag=0;    for(i=2;i<=n;i++)if(f[0][i]!=f[0][i-1]){flag=1;break;}    if(!flag){printf("%d 1\n",n);continue;}    for(j=1;j<K;j++)for(i=1;i+(1<<j-1)<=n;i++)f[j][i]=__gcd(f[j-1][i],f[j-1][i+(1<<j-1)]);    for(i=1;i<=n;i++)for(x=i;x<=n;x=y+1){      val=askgcd(y=x),l=x+1,r=n;      while(l<=r)if(askgcd(mid=(l+r)>>1)==val)l=(y=mid)+1;else r=mid-1;      a[++m]=PI(val,i,x,y);    }    sort(a+1,a+m+1,cmp);    for(i=1;i<=m;i++){      if(i==1||a[i].x!=a[i-1].x)T++;      tmp=Num();      if(a[i].i>1)ask(1,1,n,1,a[i].i-1);      if(!tmp.x)tmp=Num(1,1);else tmp.x++;      ans+=tmp-(a[i].r-a[i].l+1);      change(1,1,n,a[i].l,a[i].r);    }    printf("%d %d\n",ans.x,ans.y);  }  return 0;}

  

L. Fibonacci Equation

分类讨论。

#include<stdio.h>#include<algorithm>#include<math.h>#include<string.h>#include<string>#include<vector>#include<set>#include<map>#include<queue>#include<time.h>#include<assert.h>#include<iostream>using namespace std;typedef long long LL;typedef pair<int,int>pi;LL a[100];LL x,y,z;int main(){	/*	a[0]=0,a[1]=1;	for(int i=2;i<=30;i++)a[i]=a[i-1]+a[i-2];	for(int i=1;i<=25;i++){		printf("%lld %lld\n",a[i],a[i]*a[i]-4*a[i-1]*a[i+1]);	}	*/	while(scanf("%lld%lld%lld",&x,&y,&z)!=EOF){		if(x==0){printf("1\n");continue;}		if(y>x&&y>z){			if(y==3)printf("1\n");			else printf("2\n");		}		if(y<x&&y<z)printf("0\n");		if(y>min(x,z)&&y<max(x,z)){			if(y==1)printf("2\n");			else printf("0\n");		}		//printf("real=%lld\n",a[y]*a[y]-4*a[x]*a[z]);	}	return 0;}

  

XVII Open Cup named after E.V. Pankratiev. Eastern GP, Division 1