【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 }
View Code

 


 

 

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 }
View Code

 


 

 

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 }
View Code

 

 


 

接着更新哎。

 


 

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 }
View Code

 

posted @ 2018-09-10 23:51  甜酒果。  阅读(461)  评论(1编辑  收藏  举报