10月24日比赛

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;
}
posted @ 2022-10-24 23:00  双枫  阅读(18)  评论(0编辑  收藏  举报