C
求
範圍很小,直接暴力。
D
給你一個字符串,這個字符串中只有。讓你找三元組的數量,滿足並且
思路:
枚舉字符,若找到兩個不同的字符,,在從後面找與這兩個字符不相同的字符的數量,累加即可。複雜度。
注意別忘了這個條件。
or<int> g[5];
char s[N];
int main(){
int n = read();
scanf("%s",s+1);
rep(i,1,n){
if(s[i] == 'R') g[1].push_back(i);
else if(s[i] == 'G') g[2].push_back(i);
else g[3].push_back(i);
}
ll ans = 0;
rep(i,1,n-2){
rep(j,i+1,n-1){
if(s[i]!=s[j]){
int d = j - i;
int l = 0,r ;
int op = 1;
// cout<<i<<' '<<j<<endl;
if(s[i]!='R'&&s[j]!='R') op = 1;
else if(s[i]!='G'&&s[j]!='G') op = 2;
else if(s[i]!='B'&&s[j]!='B') op = 3;
int sz = g[op].size();
r = sz;
while(l < r){
int mid = l + r >> 1;
if(g[op][mid] > j) r = mid;
else l = mid + 1;
}
if(r != sz) {
ans += sz - r;
if(j+d<=n&&s[j+d]!=s[i]&&s[j+d]!=s[j]) ans --;
}
}
}
}
cout << ans;
}
E
題意:
給你個數,然後每個數的範圍爲。讓你求這個序列所有可能的情況時的和。
思路:
容斥。
設爲最大公約數爲的序列的數量。
最大公約數爲,序列中所有數都是的倍數。每個數可取的值有個,一共個數,所以共中情況。但是這裏面都重複的,最大公約數爲,我們要減去這些序列的數量。所以我們倒着枚舉最大公約數就很好處理了。
ll Qpow(ll a,ll b,ll p){
a = (a % p + p)%p;
ll ans = 1;
while(b){
if(b&1) ans = ans * a % p;
b >>= 1;
a = a * a%p;
}
return ans;
}
ll dp[N];
int main(){
ll n = read(),k = read();
ll ans = 0;
for(int i = k; i >= 1; -- i){
dp[i] = Qpow(k/i,n,mod);
for(int j = 2 * i;j <= k;j += i) dp[i] = (dp[i]-dp[j]+mod)%mod;
ans = (ans + 1LL*i*dp[i]+mod)%mod;
}
cout << ans;
}