題解Codeforces Global Round 5 (CF1237)


昨晚打的一場CF 感覺海星 寫一下題解:

A:送分題,先假設全部下取整求個和。如果>0就把一些負數變成上取整,如果<0就把一些正數變成上取整。

 1 #include<stdio.h>
 2 #define it register int
 3 #define il inline
 4 const int N=1000005;  5 int a[N],n,b[N],sum;  6 il void fr(int &num){  7     num=0;char c=getchar();int p=1;  8     while(c<'0'||c>'9') c=='-'?p=-1,c=getchar():c=getchar();  9     while(c>='0'&&c<='9') num=num*10+c-'0',c=getchar(); 10     num*=p; 11 } 12 int main(){ 13  fr(n); 14     for(it i=1;i<=n;++i) fr(a[i]),b[i]=a[i]/2,sum+=b[i]; 15     if(!sum){ 16         for(it i=1;i<=n;++i) printf("%d\n",b[i]); 17         return 0; 18  } 19     for(it i=1;i<=n;++i) 20         if(a[i]%2){ 21             if(a[i]<0&&sum>0) --b[i],--sum; 22             if(a[i]>0&&sum<0) ++b[i],++sum; 23  } 24     for(it i=1;i<=n;++i) 25         printf("%d\n",b[i]); 26     return 0; 27 }
View Code

B:送分題,很明顯只要前面比這個小的數的個數小於這個數在原序列中的編號,它就要罰款。樹狀數組隨便寫寫好了。

 1 #include<stdio.h>
 2 #define it register int
 3 #define il inline
 4 const int N=1000005;  5 int a[N],n,b[N],o,t[N],pos[N];  6 il void fr(int &num){  7     num=0;char c=getchar();int p=1;  8     while(c<'0'||c>'9') c=='-'?p=-1,c=getchar():c=getchar();  9     while(c>='0'&&c<='9') num=num*10+c-'0',c=getchar(); 10     num*=p; 11 } 12 il void add(it x,it num){ 13     while(x<=N) t[x]+=num,x+=(x&-x); 14 } 15 il void cal(it x,int&now){ 16     now=0; 17     while(x) now+=t[x],x-=(x&-x); 18 } 19 int main(){ 20  fr(n); 21     for(it i=1;i<=n;++i) fr(a[i]),pos[a[i]]=i; 22     for(it i=1,ans=0;i<=n;++i){ 23  fr(b[i]); 24  cal(pos[b[i]],ans); 25         if(ans<pos[b[i]]-1) ++o; 26         add(pos[b[i]],1); 27  } 28     printf("%d",o); 29     return 0; 30 }
View Code

C:真的不知道簡單和難的版本有啥區別。。每次把相同平面的排個序,然后在同一平面的先把x相同的兩兩相消,再把前后相消,然后把不同平面的上下相消。雙倍經驗拿好不送。

 1 #include<stdio.h>
 2 #include<algorithm>
 3 #define it register int
 4 #define il inline
 5 using namespace std;  6 const int N=100005;  7 int n,cnt,tot;  8 struct ky{  9     int x,y,z,id; 10 }a[N],o[N],tp[N],tpx[N]; 11 il bool cmp(ky p,ky q){ 12     return p.z<q.z; 13 } 14 il bool cmp2(ky p,ky q){ 15     return p.x^q.x?p.x<q.x:p.y<q.y; 16 } 17 il void fr(int &num){ 18     num=0;char c=getchar();int p=1; 19     while(c<'0'||c>'9') c=='-'?p=-1,c=getchar():c=getchar(); 20     while(c>='0'&&c<='9') num=num*10+c-'0',c=getchar(); 21     num*=p; 22 } 23 int main(){ 24  fr(n); 25     for(it i=1;i<=n;++i) fr(a[i].x),fr(a[i].y),fr(a[i].z),a[i].id=i; 26     sort(a+1,a+1+n,cmp); 27     for(it i=1,j;i<=n;){ 28         cnt=0;for(j=i;j<=n&&a[j].z==a[i].z;++j) tp[++cnt]=a[j]; 29         sort(tp+1,tp+1+cnt,cmp2); 30         it now=0; 31         for(it x=1,y;x<=cnt;){ 32             for(y=x;y<=cnt&&tp[y].x==tp[x].x;++y); 33             if((y-x)&1) tpx[++now]=tp[x],++x; 34             for(it tx=x;tx<y;tx+=2) printf("%d %d\n",tp[tx].id,tp[tx+1].id); 35             x=y; 36  } 37         if(now&1) o[++tot]=tpx[now],--now; 38         for(it x=1;x<=now;x+=2)  printf("%d %d\n",tpx[x].id,tpx[x+1].id); 39         i=j; 40  } 41     for(it i=1;i<=tot;i+=2) printf("%d %d\n",o[i].id,o[i+1].id); 42     return 0; 43 }
View Code

D:很顯然只要循環兩次以上就會造成死循環,手玩一下樣例就行。然后開個三倍數組寫個RMQ,每次算一下記一下這個點可以拓展的最遠點,下次就從這個最遠點開始往后拓展。

 1 #include<stdio.h>
 2 #include<math.h>
 3 #define it register int
 4 #define il inline
 5 using namespace std;  6 const int N=1000005;  7 int n,a[N],f[N][22],m,len[N];  8 il int Max(it p,it q){  9     return p>q?p:q; 10 } 11 il int Q(it l,it r){ 12     it k=log2(r-l+1);//printf("l=%d r=%d Q=%d\n",l,r,Max(f[l][k],f[r-(1<<k)+1][k]));
13     return Max(f[l][k],f[r-(1<<k)+1][k]); 14 } 15 il void fr(int &num){ 16     num=0;char c=getchar();int p=1; 17     while(c<'0'||c>'9') c=='-'?p=-1,c=getchar():c=getchar(); 18     while(c>='0'&&c<='9') num=num*10+c-'0',c=getchar(); 19     num*=p; 20 } 21 int main(){ 22     fr(n),m=n; 23     for(it i=1;i<=n;++i) fr(a[i]),a[i+n]=a[i+n+n]=a[i],f[i][0]=f[i+n][0]=f[i+n+n][0]=a[i]; 24     n*=3; 25     for(it j=1;(1<<j)<=n;++j) 26         for(it i=1;i+(1<<j)-1<=n;++i) 27             f[i][j]=Max(f[i+(1<<j-1)][j-1],f[i][j-1]); 28     it l=1,r=1; 29     for(it i=1;i<=m;++i){ 30         r=Max(r,i); 31         while(r+1<=n&&a[r+1]*2>=Q(i,r)) ++r; 32         len[i]=(r-i+1); 33  } 34     for(it i=1;i<=m;++i) printf("%d ",len[i]>2*m?-1:len[i]); 35     return 0; 36 } 
View Code

E:實際上只有0和1兩種解。。那個mod998244353就是好玩的(或者說嚇唬人的)。多畫幾種情況手算深入思考一下,對於每一種深度d只有x和x+1兩個可能有解,那么我們就不斷向上找直到有解。如果深度已經跳完了都找不到解就肯定無解啦。

 1 #include<stdio.h>
 2 #define it register int
 3 #define il inline
 4 int n,now=1;
 5 int main(){
 6     scanf("%d",&n);
 7     while(now<=n){
 8         if(now==n||now==n-1) return putchar('1'),0;
 9         now=(now&1)+(now<<1|1);
10     }
11     putchar('0');
12     return 0;
13 }
View Code

 

后面幾題先咕咕咕(看似咕咕實則不會


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM