T1
化简,推式子,然后根据性质直接枚举即可。
int main() {
int t = read();
while(t--) {
ll ans = 0;
ll a = read(),b = read(),c = read(),d = read();
for(int y = 1;y <= c*d;++ y) {
if(b*y > c*d) break;
ll res = c*d-b*y;
if(res==0) continue;
if((a*c*y)%res == 0) ans++;
}
cout<<ans; putchar('\n');
}
return 0;
}
T2
第一档分,直接 \(O(n^2)\) 枚举每一个区间然后检查这个区间是否合法即可。
第二档分,考虑异或前缀和,开桶统计这个异或和在之前出现的次数,然后累积答案即可。
正解,考虑对p和p+1异或上x,对于异或前缀来说只是修改了p位置的前缀,p+1位置又被异或回去了,那么久可以减去之前的答案,加上当前的答案即可。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int read() {
int x = 0,f = 1; char c = getchar();
while(c < '0'||c > '9') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
int n,q;
ll a[110007],cnt[110007],tot,mp[110007],cur[110007];
int main() {
// freopen("xor2.in","r",stdin);
// freopen("xor2.out","w",stdout);
cin>>n>>q;
for(int i = 1;i <= n;++ i) {
a[i] = read();
}
ll ans = 0;
mp[0] = 1;
for(int i = 1;i <= n;++ i) {
cur[i] = (cur[i-1]^a[i]);
ans += mp[cur[i]];
mp[cur[i]]++;
}
while(q--) {
ll p = read(),x = read();
mp[cur[p]]--;
ans -= mp[cur[p]];
cur[p] ^= x;
ans += mp[cur[p]];
++mp[cur[p]];
cout<<ans;
putchar('\n');
}
return 0;
}
标签:24,10,比赛,int,res,ll,while,read,异或
From: https://www.cnblogs.com/C-hen/p/16823392.html