Codeforces Round #368 (Div. 2) D &E
来源:互联网 发布:营口港荣数据大平台 编辑:程序博客网 时间:2024/04/29 17:30
题目链接: Codeforces Round #368 (Div. 2) D - Persistent Bookcase
题意:维护一个布尔矩阵s,支持四种操作:
(1) 1,x,y 将s[x][y]赋值为true(放书)
(2) 2,x,y 将s[x][y]赋值为false(取书)
(3) 3,x 将第x行所有值翻转(true->false,false->true)
(4)4,x 回到第x次操作后的情况
每次操作之后输出值为true的个数。
分析:
容易发现,操作形成了一棵树的结构:
(1) 如果第i个操作为1~3类,那么他的父亲是i-1.
(2) 如果是第4类,他父亲为x。
当时想到了这一点,但是并没有想到直接深搜能过(F**k!)。
主意正常的还原现场即可,居然一写就过。
代码如下:
#include<cstdio>#include<iostream>#include<cstdlib>#include<cmath>#include<cstring>#include<queue>#include<vector>#include<algorithm>#define LL long long#define CLEAR(xxx) memset(xxx,0,sizeof(xxx))using namespace std;const int maxn=2000+5,maxq=100000+5;int n,m,q,tot,line[maxn],ans[maxq]; //line表示每行有多少书 int e,last[maxq],Next[maxq],to[maxq];bool book[maxn][maxn]; //标记有没有书 struct query{int id,p,x,y;}ask[maxq];inline void _read(int &x){char ch=getchar(); bool mark=false;for(;!isdigit(ch);ch=getchar())if(ch=='-')mark=true;for(x=0;isdigit(ch);ch=getchar())x=x*10+ch-'0';if(mark)x=-x;}void Addedge(int x,int y){to[++e]=y;Next[e]=last[x];last[x]=e;}void DFS(int x){int i;bool flag=false; //flag=true表示当前操作有效 query& q=ask[x];if(q.p==1&&!book[q.x][q.y]){tot++; flag=true;book[q.x][q.y]=true;line[q.x]++;}else if(q.p==2&&book[q.x][q.y]){tot--; flag=true;book[q.x][q.y]=false;line[q.x]--;}else if(q.p==3){flag=true;tot+=m-2*line[q.x];line[q.x]=m-line[q.x];for(i=1;i<=m;i++)book[q.x][i]=!book[q.x][i];}ans[q.id]=tot;for(i=last[x];i!=-1;i=Next[i])DFS(to[i]);if(!flag) return ;//还原现场 if(q.p==1){tot--; book[q.x][q.y]=false;line[q.x]--;}else if(q.p==2){tot++; book[q.x][q.y]=true;line[q.x]++;}else if(q.p==3){tot+=m-2*line[q.x];line[q.x]=m-line[q.x];for(i=1;i<=m;i++)book[q.x][i]=!book[q.x][i];}}int main(){int i,j,x,y,z;_read(n);_read(m);_read(q);memset(last,-1,sizeof(last));for(i=1;i<=q;i++){ask[i].id=i;_read(ask[i].p);if(ask[i].p!=4){Addedge(i-1,i);_read(ask[i].x);if(ask[i].p!=3) _read(ask[i].y);}else {_read(x);Addedge(x,i);}}DFS(0);for(i=1;i<=q;i++) printf("%d\n",ans[i]);return 0;}
E 题目链接: Codeforces Round #368 (Div. 2) E. Garlands
大意: 一个n*m矩阵中有若干个灯泡,组成k个块(逐个给出),每个灯泡有一定的欢乐值。
有以下两种操作:
(1) SWITCH k 改变第K个块中所有灯泡的开情况(一开始全部为打开)。
(2) ASK x1,y1,x2,y2 询问左上(x1,y1),右下(x2,y2)这个矩形中,所有打开的灯泡的欢乐值之和。
分析:
由于ask操作不超过2000个,所以考虑离线操作:
将第i个块落在第j个询问的区域的灯泡的欢乐值之和预处理出来(cnt[i][j]),再记录下每个块的开关情况就好了。
答案就是所有打开的块cnt之和。
快速的修改矩阵中的元素,并查询前缀和,用二维树状数组来维护。
代码如下:
#include<cstdio>#include<iostream>#include<cstring>#include<queue>#include<vector>#include<algorithm>#define LL long long#define CLEAR(xxx) memset(xxx,0,sizeof(xxx))using namespace std;const int maxn=2000+5,maxq=1000000+5;int n,m,k,q,flip[maxq];int x1[maxq],x2[maxq],y1[maxq],y2[maxq]; //存的是询问 LL c[maxn][maxn],cnt[maxn][maxn];int is_on[maxn]; // cnt[i][j]表示第i个连通块在第j个询问范围内的欢乐值总和 struct grid{int x,y; LL w;grid(int x,int y,int w):x(x),y(y),w((LL)w){}};vector<grid> group[maxn]; //记录每个块 inline void _read(int &x){char ch=getchar(); bool mark=false;for(;!isdigit(ch);ch=getchar())if(ch=='-')mark=true;for(x=0;isdigit(ch);ch=getchar())x=x*10+ch-'0';if(mark)x=-x;}inline int lowbit(int x){return x&-x;}inline void Add(int x,int y,LL d){for(int i=x;i<=maxn;i+=lowbit(i)) //注意,这里一定要写maxn!!n会wa得很惨 for(int j=y;j<=maxn;j+=lowbit(j))c[i][j]+=d;}inline LL Sum(int x,int y){LL ans=0;for(int i=x;i>0;i-=lowbit(i))for(int j=y;j>0;j-=lowbit(j))ans+=c[i][j];return ans;} int main(){int i,j,len,xx,yy,ww,zz;_read(n);_read(m);_read(k);for(i=1;i<=k;i++){_read(zz);for(j=0;j<zz;j++){_read(xx); _read(yy); _read(ww);group[i].push_back(grid(xx,yy,ww));}}char str[10];int ask=0;_read(q);for(i=1;i<=q;i++){scanf("%s",str);if(str[0]=='S')_read(flip[i]);else {ask++;_read(x1[ask]); _read(y1[ask]);_read(x2[ask]); _read(y2[ask]);}}for(i=1;i<=k;i++){ //预处理cnt数组 for(j=0;j<group[i].size();j++)Add(group[i][j].y,group[i][j].x,group[i][j].w);for(j=1;j<=ask;j++) //一个标准的二维前缀和 cnt[i][j]=Sum(y2[j],x2[j])+Sum(y1[j]-1,x1[j]-1)-Sum(y1[j]-1,x2[j])-Sum(y2[j],x1[j]-1);for(j=0;j<group[i].size();j++)Add(group[i][j].y,group[i][j].x,-group[i][j].w);}for(i=1;i<=k;i++)is_on[i]=1; //最初全部打开 int cur=0;for(i=1;i<=q;i++){LL ans=0;if(flip[i])is_on[flip[i]]^=1; //取反 else {cur++;for(j=1;j<=k;j++)if(is_on[j]) ans+=cnt[j][cur]; cout<<ans<<endl;}}return 0;}
#include<iostream>#include<cstdio>#include<algorithm>#include<cstdlib>#include<vector>#include<cstring>using namespace std;inline void _read(long long &x){ char ch=getchar(); bool mark=false; for(;!isdigit(ch);ch=getchar())if(ch=='-')mark=true; for(x=0;isdigit(ch);ch=getchar())x=x*10+ch-'0'; if(mark)x=-x; } const long long maxn=2005;long long n,m,k,q;struct node{long long x,y,w; node(){}node(long long a,long long b,long long c){x=a;y=b;w=c;}};vector<node> a[maxn];long long work[1000005];long long c[maxn][maxn];long long cnt[maxn][maxn];bool on[maxn];long long lowbit(long long x){return x&(-x);}void modify(long long x,long long y,long long d){for(long long i=x;i<=maxn;i+=lowbit(i)){for(long long j=y;j<=maxn;j+=lowbit(j)){c[i][j]+=d;}}}long long getsum(long long x,long long y){long long sum=0;for(long long i=x;i;i-=lowbit(i)){for(long long j=y;j;j-=lowbit(j)){sum+=c[i][j];}}return sum;}long long tot=0;struct node2{long long x1,y1,x2,y2;};node2 ask[1000005];int main(){long long i,j;cin>>n>>m>>k;for(i=1;i<=k;i++){long long len;_read(len);for(j=1;j<=len;j++){long long x,y,w;_read(x);_read(y);_read(w);a[i].push_back(node(x,y,w));}}cin>>q;for(i=1;i<=q;i++){char s[10];scanf("%s",s);if(s[0]=='S'){_read(work[i]);}else{tot++;_read(ask[tot].x1);_read(ask[tot].y1);_read(ask[tot].x2);_read(ask[tot].y2);}}for(i=1;i<=k;i++){for(j=0;j<a[i].size();j++){modify(a[i][j].x,a[i][j].y,a[i][j].w);}for(j=1;j<=tot;j++){cnt[i][j]=getsum(ask[j].x2,ask[j].y2)+getsum(ask[j].x1-1,ask[j].y1-1)-getsum(ask[j].x2,ask[j].y1-1)-getsum(ask[j].x1-1,ask[j].y2);}for(j=0;j<a[i].size();j++){modify(a[i][j].x,a[i][j].y,-a[i][j].w);}}for(i=1;i<=k;i++)on[i]=true;long long l=0;for(i=1;i<=q;i++){if(work[i]){on[work[i]]=(!on[work[i]]);}else{long long ans=0;l++;for(j=1;j<=k;j++){if(on[j])ans+=cnt[j][l];}printf("%I64d\n",ans);}}}
- Codeforces Round #368 (Div. 2) D &E
- Codeforces Round #184 (Div. 2) D、E
- Codeforces Round #283 (Div. 2) D,E
- Codeforces Round #306 (Div. 2) D-E
- Codeforces Round #345 (Div. 2) D,E
- Codeforces Round #443 (Div. 2) D,E
- Codeforces Round #368 (Div 2) A,B,C,D,E
- Codeforces Round #186 (Div. 2)A、B、C、D、E
- Codeforces Round #237 (Div. 2) E. Maze 1D
- Codeforces Round #258 (Div. 2)-(A,B,C,D,E)
- Codeforces Round #261 (Div. 2) A,B,C,D,E
- Codeforces Round #263 (Div. 2) A,B,C,D,E
- Codeforces Round #264 (Div. 2) A,B,C,D,E
- Codeforces Round #274 (Div. 2) 解题报告 (C D E)
- Codeforces Round #277 (Div. 2) A,B,C,D,E
- Codeforces Round #280 (Div. 2 A,B,C,D,E)
- Codeforces Round #287 (Div. 2) A、B、C、D、E
- Codeforces Round #287 (Div. 2)A,B,C,D,E
- 在ASP.NET MVC中简单使用跨域Ajax
- C++中SetConsoleCtrlHandler 处理控制台消息
- 2016暑期集训13 B瞬间移动 HDU 5698
- vim学习
- java 关键字static 使用
- Codeforces Round #368 (Div. 2) D &E
- Matlab问答day4
- Java 中 Comparable 和 Comparator 比较
- springmvc的基本配置
- apache 配置虚拟主机的小陷阱(不注意,还真能踩坑)
- 重载与覆写的区别?(或Overloading与Overrid的区别?)
- struts2中的web.xml配置文件详解
- HDU3400
- Django 外键为本身(Python3)