【gdkoi2016】【day1t1】【魔卡少女】【cardcaptor】【线段树】
来源:互联网 发布:网络节点怎么设置 编辑:程序博客网 时间:2024/05/01 06:42
魔卡少女cardcaptor
题意:一段数,支持单点修改,查询一段区间内子区间异或和的和。
具体做法:先做个异或前缀和,[l,r] 异或和即∑sum[i]⊕sum[j](l−1<=i,j<=r)(⊕为异或) ,每个位对答案的贡献为[l−1,r] 中零的个数乘以一的个数,至于为什么可以自行脑补。对于修改可以把不同的位的[x,n] 的零和一的个数调换,对此可以懒标记区间修改,但是一定要记得修改完儿子后,把自己的零和一的个数重新统计一下。为此我调试了半天~~~。可是常数巨大,贴上tle80分的代码。
#include<set>#include<cmath>#include<vector>#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<algorithm>#define ll long long#define fo(i,j,k) for(int i=j;i<=k;i++)#define fd(i,j,k) for(int i=j;i>=k;i--)using namespace std;int const oo=2147483647;int const maxn=100000;int const p=100000007;typedef struct{int x,y;}note;inline int get(){ char ch=getchar();while((ch!='-')&&((ch<'0')||(ch>'9')))ch=getchar(); int u=1,v=0;if(ch=='-')u=-1;else v=ch-'0';ch=getchar(); while((ch>='0')&&(ch<='9'))v=v*10+ch-'0',ch=getchar(); return u*v;}inline char getch(){ char ch=getchar(); while((ch<'A')||(ch>'Z'))ch=getchar(); return ch;}int n,m,a[maxn+10],tr[maxn*6+10][10+1][2],exchange[maxn*6+10][10+1];inline void scan(){ //srand(time(NULL)); //rand()%100; n=get(); fo(i,1,n) a[i]=get();}void add(int t,int l,int r,int i,int j,int k){ tr[t][i][j]++; if(l==r)return; int m=(l+r)/2; if(k<=m)add(t*2,l,m,i,j,k); else add(t*2+1,m+1,r,i,j,k);}void relax(int t,int i){ if(exchange[t][i]){ exchange[t][i]=false; int tt=tr[t][i][0]; tr[t][i][0]=tr[t][i][1]; tr[t][i][1]=tt; exchange[t*2][i]=!exchange[t*2][i]; exchange[t*2+1][i]=!exchange[t*2+1][i]; }}void updata(int t,int i){ tr[t][i][0]=tr[t*2][i][0]+tr[t*2+1][i][0]; tr[t][i][1]=tr[t*2][i][1]+tr[t*2+1][i][1];}ll get(int t,int l,int r,int i,int j,int l1,int r1){ relax(t,i); if((l==l1)&&(r==r1))return tr[t][i][j]; int m=(l+r)/2,ans=0; if(r1<=m)ans=get(t*2,l,m,i,j,l1,r1); else if(m<l1)ans=get(t*2+1,m+1,r,i,j,l1,r1); else ans=get(t*2,l,m,i,j,l1,m)+get(t*2+1,m+1,r,i,j,m+1,r1); relax(t*2,i);relax(t*2+1,i); updata(t,i); return ans;}void change(int t,int l,int r,int i,int l1,int r1){ if((l==l1)&&(r==r1)) exchange[t][i]=!exchange[t][i]; relax(t,i); if((l==l1)&&(r==r1))return; int m=(l+r)/2; if(r1<=m)change(t*2,l,m,i,l1,r1); else if(m<l1)change(t*2+1,m+1,r,i,l1,r1); else{ change(t*2,l,m,i,l1,m); change(t*2+1,m+1,r,i,m+1,r1); } relax(t*2,i);relax(t*2+1,i); updata(t,i);}inline void solve(){ int sum=0; fo(i,0,n){ int tmp=sum; fo(j,1,10){ add(1,0,n,j,tmp%2,i); tmp/=2; } sum^=a[i+1]; } m=get(); fo(i,1,m){ char ch=getch(); int x=get(),y=get(); if(ch=='Q'){ ll ans=0; fd(j,10,1) ans=((((1<<(j-1))*get(1,0,n,j,0,x-1,y))%p*get(1,0,n,j,1,x-1,y))%p+ans)%p; printf("%lld\n",ans); } else{ int tmp=y; fo(j,1,10){ if(a[x]%2!=tmp%2) change(1,0,n,j,x,n); a[x]/=2; tmp/=2; } a[x]=y; } }}int main(){ scan(); solve(); return 0;}
1 0
- 【gdkoi2016】【day1t1】【魔卡少女】【cardcaptor】【线段树】
- [GDKOI2016] Day1 魔卡少女 线段树
- [GDKOI2016]魔卡少女
- 【JZOJ4359】【GDKOI2016】魔卡少女
- 【GDKOI2016】魔卡少女Code&&Details
- GDKOI2016 Day 1 T1 魔卡少女
- 【线段树合并】【bzoj4399】: 魔法少女LJJ
- Day1T1
- GDKOI 2016 魔卡少女
- [线段树 合并] BZOJ 4399 魔法少女LJJ
- BZOJ 4399 魔法少女LJJ 线段树合并
- 【bzoj 4399】魔法少女LJJ(线段树合并)
- BZOJ[4399]魔法少女LJJ 线段树合并
- GDKOI2016
- 前缀和or线段树____计数少女(2016swust信息院赛)
- bzoj 4399 魔法少女 权值线段树合并+并查集
- [2017纪中10-25]天才绅士少女助手克里斯蒂娜 线段树
- 少女
- ios 在已有项目添加CoreData
- libRTMP使用说明
- jQuery是什么?
- 2016
- Run Loop详解
- 【gdkoi2016】【day1t1】【魔卡少女】【cardcaptor】【线段树】
- Android开发Tips(5)
- KVO探究
- 查询本机IP及精确地理位置
- java中HashMap详解
- HashSet,TreeSet和LinkedHashSet的区别
- java中IO的用法
- 新装系统之后的配置
- JAVA实现远程文件读取