【HDOJ6610】Game(序列带修莫队)
题意:有n堆石子,第n堆有a[i]个,A先选择一个范围【L,R】,B选择一个子区间【l,r】,之后照nim游戏的规则进行
现在有询问与操作
每次询问B在给定的【L,R】内有多少种子区间的取法使得A必胜
每次操作会交换第x堆和第x+1堆石头
0<=a[i]<=1e6,n,m<=1e5
思路:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef pair<int,int> PII; 7 typedef pair<ll,ll> Pll; 8 typedef vector<int> VI; 9 typedef vector<PII> VII; 10 //typedef pair<ll,ll>P; 11 #define N 3000010 12 #define M 100010 13 #define fi first 14 #define se second 15 #define MP make_pair 16 #define pb push_back 17 #define pi acos(-1) 18 #define mem(a,b) memset(a,b,sizeof(a)) 19 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 20 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 21 #define lowbit(x) x&(-x) 22 #define Rand (rand()*(1<<16)+rand()) 23 #define id(x) ((x)<=B?(x):m-n/(x)+1) 24 #define ls p<<1 25 #define rs p<<1|1 26 27 const int MOD=1e9+7,inv2=(MOD+1)/2; 28 double eps=1e-4; 29 int INF=0x7fffffff; 30 int inf=1e9; 31 int dx[4]={-1,1,0,0}; 32 int dy[4]={0,0,-1,1}; 33 34 struct Q 35 { 36 int l,r,cur,id; 37 }q[M]; 38 39 struct P 40 { 41 int x,pre,now; 42 }p[M]; 43 44 int a[M],b[M],v[M],cnt[N],pos[M]; 45 ll sum,ans[M]; 46 47 bool cmp(Q a,Q b) 48 { 49 return pos[a.l]<pos[b.l] 50 ||pos[a.l]==pos[b.l]&&pos[a.r]<pos[b.r] 51 ||pos[a.l]==pos[b.l]&&pos[a.r]==pos[b.r]&&a.cur<b.cur; 52 } 53 54 int read() 55 { 56 int v=0,f=1; 57 char c=getchar(); 58 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 59 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 60 return v*f; 61 } 62 63 void go(int x) 64 { 65 if(v[x]) 66 { 67 cnt[b[x]]--; 68 sum-=cnt[b[x]]; 69 } 70 else 71 { 72 sum+=cnt[b[x]]; 73 cnt[b[x]]++; 74 } 75 v[x]^=1; 76 } 77 78 void update(int x) 79 { 80 if(!x) return; 81 if(v[x]) 82 { 83 go(x); 84 b[x]^=a[x]; 85 swap(a[x],a[x+1]); 86 b[x]^=a[x]; 87 go(x); 88 } 89 else 90 { 91 b[x]^=a[x]; 92 swap(a[x],a[x+1]); 93 b[x]^=a[x]; 94 } 95 } 96 97 int main() 98 { 99 int n,m; 100 while(scanf("%d%d",&n,&m)!=EOF) 101 { 102 mem(cnt,0); 103 mem(v,0); 104 mem(a,0); 105 mem(b,0); 106 int S=max(10,(int)pow(n,2.0/3)); 107 a[1]=b[1]=0; pos[1]=0; 108 rep(i,2,n+1) 109 { 110 a[i]=read(); 111 b[i]=b[i-1]^a[i]; 112 pos[i]=(i-1)/S; 113 } 114 int l1=0,l2=0; 115 rep(i,1,m) 116 { 117 int op=read(); 118 if(op==1) 119 { 120 int x=read(),y=read(); 121 q[++l1].l=x; 122 q[l1].r=y+1; 123 q[l1].id=l1; 124 q[l1].cur=l2; 125 } 126 else 127 { 128 int x=read(); 129 p[++l2].x=x+1; 130 } 131 132 } 133 sort(q+1,q+l1+1,cmp); 134 int L=1,R=0,T=0; 135 sum=0; 136 rep(i,1,l1) 137 { 138 while(T<q[i].cur) 139 { 140 T++; 141 update(p[T].x); 142 } 143 144 while(T>q[i].cur) 145 { 146 update(p[T].x); 147 T--; 148 } 149 150 while(L>q[i].l) go(--L); 151 while(L<q[i].l) go(L++); 152 while(R>q[i].r) go(R--); 153 while(R<q[i].r) go(++R); 154 ll len=R-L+1; 155 ans[q[i].id]=len*(len-1)/2-sum; 156 } 157 rep(i,1,l1) printf("%I64d\n",ans[i]); 158 } 159 160 return 0; 161 }
null