Codeforces Round #368 (Div. 2)

Problem A  Brain's Photos

题目大意

  n行m列的矩形,每个格子有一种颜色。如果含有C、M、Y则输出#Color,否则输出#Black&White。

解题分析

  = =

参考程序

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <string>
 8 #include <vector>
 9 #include <cstdio>
10 #include <cstdlib>
11 #include <cstring>
12 #include <cassert>
13 #include <iostream>
14 #include <algorithm>
15 #pragma comment(linker,"/STACK:102400000,102400000")
16 using namespace std;
17 
18 #define V 100008             
19 #define E 2000008    
20 #define LL long long
21 #define lson l,m,rt<<1
22 #define rson m+1,r,rt<<1|1 
23 #define clr(x,v) memset(x,v,sizeof(x));
24 #define bitcnt(x) __builtin_popcount(x)
25 #define rep(x,y,z) for (int x=y;x<=z;x++)
26 #define repd(x,y,z) for (int x=y;x>=z;x--)
27 const int mo  = 1000000007;
28 const int inf = 0x3f3f3f3f;
29 const int INF = 2000000000;
30 /**************************************************************************/ 
31 int n,m;
32 char s[10];
33 int main(){
34     scanf("%d%d",&n,&m);
35     int ok=1;
36     for (int i=1;i<=n;i++)
37         for (int j=1;j<=m;j++)
38         {
39             scanf("%s",s);
40             if (s[0]=='C' || s[0]=='M' || s[0]=='Y') ok=0;
41         }
42     if (ok) printf("#Black&White\n"); else printf("#Color\n");
43 }
View Code

Problem B  Bakery

题目大意

  给一张n个点m条边有边权的无向图,有k个点是仓库。要求在某个非仓库点开面包店,使得其与最近的仓库的距离最小。

解题分析

  枚举每个仓库点,再遍历其相邻点,统计对答案的贡献。

  时间复杂度O(E)。

参考程序

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <string>
 8 #include <vector>
 9 #include <cstdio>
10 #include <cstdlib>
11 #include <cstring>
12 #include <cassert>
13 #include <iostream>
14 #include <algorithm>
15 #pragma comment(linker,"/STACK:102400000,102400000")
16 using namespace std;
17 
18 #define V 100008             
19 #define E 200008    
20 #define LL long long
21 #define lson l,m,rt<<1
22 #define rson m+1,r,rt<<1|1 
23 #define clr(x,v) memset(x,v,sizeof(x));
24 #define bitcnt(x) __builtin_popcount(x)
25 #define rep(x,y,z) for (int x=y;x<=z;x++)
26 #define repd(x,y,z) for (int x=y;x>=z;x--)
27 const int mo  = 1000000007;
28 const int inf = 0x3f3f3f3f;
29 const int INF = 2000000000;
30 /**************************************************************************/ 
31 
32 int n,m,k;
33 
34 struct line{
35     int u,v,w,nt;
36 }eg[E];
37 int lt[V],sum=1;
38 int ok[V];
39 void add(int u,int v,int w){
40     eg[++sum].u=u; eg[sum].v=v; eg[sum].w=w; eg[sum].nt=lt[u]; lt[u]=sum;
41 }
42 int main(){
43     clr(ok,0);
44     scanf("%d%d%d",&n,&m,&k);
45     rep(i,1,m){
46         int u,v,w;
47         scanf("%d %d %d",&u,&v,&w);
48         add(u,v,w);
49         add(v,u,w);
50     }
51     rep(i,1,k){
52         int x;
53         scanf("%d",&x);
54         ok[x]=1;
55     }
56     int ans=INF;
57     rep(u,1,n)
58         if (ok[u]){
59             for (int i=lt[u];i;i=eg[i].nt){
60                 int v=eg[i].v;
61                 if (!ok[v]) ans=min(ans,eg[i].w);
62             }
63         }
64     printf("%d\n",ans==INF?-1:ans);
65 }
View Code

Problem C  Pythagorean Triples

题目大意

  给定一个数n,要求输出两个数m,k,使得n、m、k构成一组勾股数。

  (n<=10^9,m,k<=10^10^18)

解题分析

  对于1,2特判一下无解。

  对于2^i的数字,等于将3,4,5这3个数扩大若干倍。

  对于奇数x,可以构造出(x^2+1)/2 , (x^2-1)/2 满足条件。

  对于偶数x,可以将其经过若干次除2后变成奇数,再扩大回去。

参考程序

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <string>
 8 #include <vector>
 9 #include <cstdio>
10 #include <cstdlib>
11 #include <cstring>
12 #include <cassert>
13 #include <iostream>
14 #include <algorithm>
15 #pragma comment(linker,"/STACK:102400000,102400000")
16 using namespace std;
17 
18 #define N 508             
19 #define M 50008    
20 #define LL long long
21 #define lson l,m,rt<<1
22 #define rson m+1,r,rt<<1|1 
23 #define clr(x,v) memset(x,v,sizeof(x));
24 #define bitcnt(x) __builtin_popcount(x)
25 #define rep(x,y,z) for (int x=y;x<=z;x++)
26 #define repd(x,y,z) for (int x=y;x>=z;x--)
27 const int mo  = 1000000007;
28 const int inf = 0x3f3f3f3f;
29 const int INF = 2000000000;
30 /**************************************************************************/ 
31 
32 LL x;
33 
34 int main(){
35     scanf("%I64d",&x);
36     int num=0;
37     while (x % 2 ==0){
38         if (x==4) break;
39         num++;
40         x/=2;
41     }
42     if (x==4){
43         LL y=3,z=5;
44         while (num){
45             y*=2;
46             z*=2;
47             num--;
48         }
49         printf("%I64d %I64d\n",y,z);
50         return 0;
51     }
52     LL y=(x*x+1)/2,z=y-1;
53     if (z>0){
54         while (num){
55             y*=2;
56             z*=2;
57             num--;
58         }
59         printf("%I64d %I64d\n",z,y);
60     }
61     else printf("-1\n");
62 
63 }
View Code

Problem D  Persistent Bookcase

题目大意

  有一个n*m的书架,每个格子可以放一本书,要求支持一下四种操作。

  操作1:在a[i,j]位置上放一本书,若已经有书则不放。

  操作2:将a[i,j]位置上的书移走,若没有书则不移动。

  操作3:将第i行的书进行整体操作,若有书则移走,若没书则放置一本书。

  操作4:回到之前某个操作的状态。

解题分析

  虽然题意中强调了这是一种可持久化的数据结构,但一般来说这种题不会考虑用可持久化来解决= =

  由于有操作4,数据又没有强制在线,一个自然的想法就是离线处理。

  按照询问的顺序,可以建成一棵询问树,每次递归回溯解决即可。

  对于维护操作3,可以打标记处理,也可以直接开n个bitset,每次用自带的函数flip暴力修改。

参考程序

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <bitset>
 8 #include <string>
 9 #include <vector>
10 #include <cstdio>
11 #include <cstdlib>
12 #include <cstring>
13 #include <cassert>
14 #include <iostream>
15 #include <algorithm>
16 #pragma comment(linker,"/STACK:102400000,102400000")
17 using namespace std;
18 
19 #define N 100008          
20 #define M 200008  
21 #define LL long long
22 #define lson l,m,rt<<1
23 #define rson m+1,r,rt<<1|1 
24 #define clr(x,v) memset(x,v,sizeof(x));
25 #define bitcnt(x) __builtin_popcount(x)
26 #define rep(x,y,z) for (int x=y;x<=z;x++)
27 #define repd(x,y,z) for (int x=y;x>=z;x--)
28 const int mo  = 1000000007;
29 const int inf = 0x3f3f3f3f;
30 const int INF = 2000000000;
31 /**************************************************************************/ 
32 
33 bitset <1008> a[1008];
34 int ans[M];
35 int f[N];
36 int n,m,k;
37 struct node{
38     int type,x,y;
39 }q[M];
40 struct line{
41     int u,v,nt;
42 }eg[M];
43 int lt[N],sum=1;
44 void add(int u,int v){
45     eg[++sum].u=u; eg[sum].v=v; eg[sum].nt=lt[u]; lt[u]=sum; f[v]=u;
46 }
47 void dfs(int u){
48     //printf("%d %d %d %d\n",u,q[u].type,f[u],ans[f[u]] );
49     int p;
50     if (q[u].type==4){
51         ans[u]=ans[f[u]];
52     }
53     if (q[u].type==1){
54         p = a[q[u].x][q[u].y];
55         a[q[u].x][q[u].y]=1;
56         if (p==1) ans[u]=ans[f[u]]; else ans[u]=ans[f[u]]+1;
57     }
58     if (q[u].type==2){
59         p = a[q[u].x][q[u].y];
60         a[q[u].x][q[u].y]=0;
61         if (p==1) ans[u]=ans[f[u]]-1; else ans[u]=ans[f[u]];
62     }
63     if (q[u].type==3){
64         int one=a[q[u].x].count();
65         a[q[u].x].flip();
66         if (a[q[u].x][0]==0) one=one-(1008-m);
67         ans[u]=ans[f[u]]-one+m-one;
68     }
69     for (int i=lt[u];i;i=eg[i].nt)
70         dfs(eg[i].v);
71     if (q[u].type==1||q[u].type==2){
72         a[q[u].x][q[u].y]=p;
73     }
74     if (q[u].type==3){
75         a[q[u].x].flip();
76     }
77     
78 }
79 
80 int main(){
81     scanf("%d %d %d",&n,&m,&k);
82     rep(i,1,k){
83         int x,y,z;
84         scanf("%d%d",&x,&y);
85         if (x==1||x==2) scanf("%d",&z);
86         q[i].type=x;
87         q[i].x=y;
88         q[i].y=z;
89         if (q[i].type==4){
90             add(q[i].x,i);
91         }
92         else add(i-1,i);
93     }
94     dfs(0);
95     //a[1][0]=1;
96     //a[1][1]=1;
97     //a[1].flip();
98     rep(i,1,k) printf("%d\n",ans[i] );    
99 }
View Code

 Problem E Garlands

题目大意

  给一个n*m的矩阵,每个点有点权。上面有k条链,每条链长度为len,链上的点有点权。

保证所有链不会相交。每条链有个开关,若关闭则不计算链上的点权。要求支持两种操作。

  操作1:询问某个子矩阵的权值和。操作2:开关某条链。

  n,m,k,操作1总数<=2000, 操作总数<=1000000

解题分析

  由于操作1的数量较少,考虑离线处理询问。

  用二维树状数组计算每条链对每个询问的贡献。

  时间复杂度 (n^2logn^2)

  也可以用前缀和进行维护,将询问按照x坐标排序后,用一维树状数组维护前缀和。

  时间复杂度 (n^2logn)

参考程序

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <string>
 8 #include <vector>
 9 #include <cstdio>
10 #include <cstdlib>
11 #include <cstring>
12 #include <cassert>
13 #include <iostream>
14 #include <algorithm>
15 #pragma comment(linker,"/STACK:102400000,102400000")
16 using namespace std;
17 
18 #define N 2008             
19 #define M 50008    
20 #define LL long long
21 #define lson l,m,rt<<1
22 #define rson m+1,r,rt<<1|1 
23 #define clr(x,v) memset(x,v,sizeof(x));
24 #define bitcnt(x) __builtin_popcount(x)
25 #define rep(x,y,z) for (int x=y;x<=z;x++)
26 #define repd(x,y,z) for (int x=y;x>=z;x--)
27 const int mo  = 1000000007;
28 const int inf = 0x3f3f3f3f;
29 const int INF = 2000000000;
30 /**************************************************************************/ 
31 int n,m,k,qcnt,wcnt;
32 int len[N],flag[N],x[N][N],y[N][N],z[N][N];
33 char s[10];
34 LL ans[N][N];
35 struct que{
36     int type,a,b,c,d;
37 }q[2000008],w[N];
38 struct Binaty_Indexed_Tree{
39     LL a[N][N];
40     void clear(){
41         clr(a,0);
42     }
43     void insert(int x,int y,int val){
44         for (int i=x;i<N;i+=i & (-i))
45             for (int j=y;j<N;j+=j & (-j))
46                 a[i][j]+=val;
47     }
48     LL sigma(int x,int y){
49         if (x==0||y==0) return 0;
50         LL res=0;
51         for (int i=x;i>0;i-=i & (-i))
52             for (int j=y;j>0;j-=j & (-j))
53                 res+=a[i][j];
54         return res;
55     }
56     LL query(int x1,int y1,int x2,int y2){
57         LL res=0;
58         res = sigma(x2,y2)-sigma(x1-1,y2)-sigma(x2,y1-1)+sigma(x1-1,y1-1);
59         return res;
60     }
61 }T;
62 int main(){
63     scanf("%d%d%d",&n,&m,&k);
64     rep(i,1,k){
65         scanf("%d",&len[i]);
66         rep(j,1,len[i]) scanf("%d%d%d",&x[i][j],&y[i][j],&z[i][j]);
67     }
68     scanf("%d",&qcnt); wcnt=0;
69     rep(i,1,qcnt){
70         scanf("%s",s);
71         if (s[0]=='A'){
72             q[i].type=1;
73             scanf("%d%d%d%d",&q[i].a,&q[i].b,&q[i].c,&q[i].d);
74             w[++wcnt]=q[i];
75         }
76         if (s[0]=='S'){
77             q[i].type=2;
78             scanf("%d",&q[i].a);
79         }
80     }
81     T.clear();
82     rep(i,1,k){
83         rep(j,1,len[i]) T.insert(x[i][j],y[i][j],z[i][j]);
84         rep(j,1,wcnt) ans[j][i]=T.query(w[j].a,w[j].b,w[j].c,w[j].d);
85          rep(j,1,len[i]) T.insert(x[i][j],y[i][j],-z[i][j]);
86     }
87     int id=0;
88     rep(j,1,k) flag[j]=1;
89     rep(i,1,qcnt){
90         if (q[i].type==2) flag[q[i].a]^=1;
91         if (q[i].type==1){
92             LL res=0; id++;
93             rep(j,1,k) if (flag[j]) res+=ans[id][j];
94             printf("%I64d\n",res);
95         }    
96     }
97 }
View Code

 

posted @ 2016-08-21 12:29  rpSebastian  阅读(270)  评论(0编辑  收藏  举报