【2018ACM/ICPC网络赛】徐州赛区
呃。自闭了自闭了。我才不会说我写D写到昏天黑地呢。
I Characters with Hash
题目链接:https://nanti.jisuanke.com/t/31461
题意:给你一个字符串s,一个种子字母L。根据 |int(L) - s[i]|公式的到hash后的字符,如果是个位数就变成两位数,最后去掉前导0计算字符串长度。也就是0->00 7->07.最后统计如果前面有0就都去掉。如果在中间qwq就不用啦。
题解:暴力模拟//先开始卡题意。。初始长度就设成2n好了。如果判断前面有0就-=2,如果是个位数的话-=1,后面都是长度为2啦。其实也就是判断一下最前面的字符即可。
虽然这题水,但是我真的卡题意了。都不好意思说自己过了六级。, 有个坑。。长度为0的时候输出1。
代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <string> 4 using namespace std; 5 6 string s; 7 8 int main(){ 9 int T; 10 scanf("%d", &T); 11 while(T --){ 12 int n; 13 char seed; 14 cin>>n>>seed; 15 cin>>s; 16 int ans = 2 * n; 17 //只需要判断第一个是不是为0还是个位数 18 for(int i = 0; i < n ;i++){ 19 int tmp = abs(seed-s[i]); 20 if(tmp == 0){ 21 ans -= 2; 22 } 23 else if(tmp < 10){ 24 ans -= 1; 25 break; 26 } 27 else{ 28 break; 29 } 30 } 31 if(ans == 0) 32 ans = 1; 33 cout<<ans<<endl; 34 } 35 return 0; 36 }
H Ryuji doesn't want to study
题目链接:https://nanti.jisuanke.com/t/31460
题意:两个操作,1、l,r 查询a[l]*Len + a[l+1]*(Len-1) … + a[r]的和。
2、b c,把a[b]->c
题解:树状数组维护一下a[i] * (r-i+1)的和,以及维护一下a[i]。。(学长的代码。!!超棒)
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 using namespace std; 6 #define ll long long 7 8 ll a[100010], b[100010], c[100010]; 9 10 ll lowbit(ll x){ 11 return x&(-x); 12 } 13 14 int n; 15 ll sum(ll x){ 16 ll s = 0; 17 while(x > 0){ 18 s += c[x]; 19 x -= lowbit(x); 20 } 21 return s; 22 } 23 24 void add(int x, ll val){ 25 while(x <= n){ 26 c[x] += val; 27 x += lowbit(x); 28 } 29 } 30 31 ll sum1(ll x){ 32 ll s = 0; 33 while(x > 0){ 34 s += b[x]; 35 x -= lowbit(x); 36 } 37 return s; 38 } 39 40 void add1(int x,ll val){ 41 while( x <= n){ 42 b[x] += val; 43 x += lowbit(x); 44 } 45 } 46 47 int main(){ 48 int q; 49 scanf("%d%d", &n, &q); 50 for(int i = 1;i <= n; i++){ 51 scanf("%lld", &a[i]); 52 add(i, a[i] * (n - i + 1)); 53 add1(i, a[i]); 54 } 55 for(int i = 1; i <= q; i++){ 56 int l, r, op; 57 scanf("%d", &op); 58 if(op == 1){ 59 scanf("%d%d", &l, &r); 60 printf("%lld\n", sum(r) - sum(l-1) - (sum1(r) - sum1(l-1)) * (n - r)); 61 } else { 62 scanf("%d%d", &l, &r); 63 add(l, (r - a[l]) * (n - l + 1)); 64 add1(l, r - a[l]); 65 a[l] = r; 66 } 67 } 68 return 0; 69 }
G Trace
题目链接:https://nanti.jisuanke.com/t/31459
题意:有一波一波的海浪,每一波海浪都会覆盖上一波的部分痕迹。求海浪打完后所留下的痕迹长度。海浪是个矩形,左下角0,0,右上角题目输入的x,y。
题解:这个题很毒。TLE了好多发。队友后面直接崩溃了。QAQ。用两个set维护。倒着求,找到当前比输入的x,y第一个小的sx,sy。ans += abs(x-sx),ans+= abs(y-sy)。大概这个意思。赛后在群里看到代码了才恍然大悟。emmm..还有就是对set不太熟悉。哎。
代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <string> 4 #include <set> 5 using namespace std; 6 #define ll long long 7 const int maxn = 1e5+5; 8 int n,m; 9 int x[maxn],y[maxn]; 10 set<int> xx; 11 set<int> yy; 12 set<int>::iterator it; 13 ll ans = 0; 14 void addl(int sx,int sy){ 15 it = xx.lower_bound(sx); 16 if(it == xx.begin()) 17 ans += sx; 18 else { 19 it--; 20 ans += sx - *it; 21 } 22 it = yy.lower_bound(sy); 23 if(it == yy.begin()) 24 ans += sy; 25 else{ 26 it--; 27 ans += sy - *it; 28 } 29 } 30 int main(){ 31 cin>>n; 32 for(int i=0; i<n; i++) 33 cin>>x[i]>>y[i]; 34 for(int i = n-1; i >= 0; i--){ 35 addl(x[i],y[i]); 36 xx.insert(x[i]); 37 yy.insert(y[i]); 38 } 39 cout<<ans<<endl; 40 return 0; 41 }
接着更新哎。
D Easy Math
题目链接:https://nanti.jisuanke.com/t/31456
题意:计算$ ∑^{m}_{i = 1}$ µ (i*n)
题解:呃。真的不是很想面对这题。当时推出来直接上杜教筛,就被打爆了。对不起队友。
正经题解:
设f(m,n) = $ ∑^{m}_{i = 1}$ µ (i*n)
f(m,n) = $∑^{m}_{i = 1}$ µ(i)*µ(n) * [gcd(i,n) == 1]
= $∑^{m}_{i = 1}$ µ(i)*µ(n) * $∑_{ d|(i,n)}$µ(d)
= $\mu(n)\sum\limits_{d|n} \mu(d) \sum\limits^{\lfloor m/d \rfloor}_{i = 1} \mu(i*d)$
= $\mu(n)\sum\limits_{d|n} \mu(d) f(\lfloor (m/d) \rfloor,d)$
几种终止情况
m = 0,f(m,n) = 0
m = 1,f(m,n) = µ(n)
n = 1,f(m,n) =$\sum\limits^{m}_{i = 1} \mu(i)$ ->杜教筛
代码:
1 #include <cstdio> 2 #include <map> 3 #include <iostream> 4 #include <map> 5 using namespace std; 6 #define ll long long 7 const int N = 5e6; 8 9 ll n,m; 10 11 int mu[N+10],pri[N+10],top; 12 bool mark[N+10]; 13 map<ll,ll>V; 14 15 int cnt; 16 ll p[N]; 17 ll val[N]; 18 int bit[N]; 19 20 21 /*杜教筛*/ 22 void init(){ 23 mu[1]=1; 24 for(int i = 2; i <= N; i++){ 25 if(!mark[i]){ 26 pri[++top] = i; 27 mu[i] = -1; 28 } 29 for(int j = 1; j <= top && i * pri[j] <= N; j++){ 30 mark[ i * pri[j] ] = true; 31 if(i % pri[j] == 0) 32 break; 33 mu[ i * pri[j] ] = -mu[i]; 34 } 35 } 36 for(int i = 2; i <= N; i++) 37 mu[i] += mu[i-1]; 38 } 39 ll calc(ll x){ 40 if(x <= N) 41 return mu[x]; 42 if(V[x]) 43 return V[x]; 44 ll ans = 1; 45 for(ll i = 2,r; i <= x; i = r+1){ 46 r = x/(x/i); 47 ans -= calc(x/i) * (r-i+1); 48 } 49 50 V[x] = ans; 51 return ans; 52 } 53 54 ll phi(ll x){ 55 return ( (bit[x] & 1) ? -1 : 1 ); 56 } 57 58 ll solve(ll m, ll n) { 59 if (bit[n] == 0) 60 return calc(m); 61 if (m == 0) 62 return 0; 63 if (m == 1) 64 phi(n); 65 ll ans = 0; 66 for (ll i = n; ; i = (i-1) & n){ 67 ans += phi(i) * solve( m/val[i] , i); 68 if (!i) 69 break; 70 } 71 return ans * phi(n); 72 } 73 74 75 int main(){ 76 init(); 77 cin>>m>>n; 78 ll x = n; 79 cnt = 0; 80 int flag = 0; 81 for( ll i = 2 ; i * i <= x ;i++){ 82 if(x%i == 0){ 83 //判断有偶数个因子 84 int t = (x/i) % i; 85 if(t == 0){ 86 flag = 1; 87 break; 88 } 89 //不是的话加入 90 p[cnt++] = i; 91 while(x % i == 0){ 92 x /= i; 93 } 94 } 95 } 96 if(flag){ 97 cout<<0<<endl; 98 return 0; 99 } 100 if(x > 1) 101 p[cnt++] = x; 102 for(int i = 0; i < (1<<cnt); i++){ 103 bit[i] = 0; 104 val[i] = 1; 105 for(int j = 0; j < cnt; j++){ 106 if(i & (1<<j) ){ 107 bit[i]++; 108 val[i] *= p[j]; 109 } 110 } 111 } 112 cout<<solve(m,(1<<cnt)-1)<<endl; 113 return 0; 114 }