Codeforces_817

A.要求坐标差为移动距离的两倍。

#include<bits/stdc++.h>
using namespace std;

int main()
{
    ios::sync_with_stdio(0);
    int x1,x2,y1,y2,x,y;
    cin >> x1 >> y1 >> x2 >> y2 >> x >> y;
    int xx = abs(x1-x2),yy = abs(y1-y2);
    if(xx%x || yy%y)
    {
        cout << "NO" << endl;
        return 0;
    }
    if(xx/x%2 == yy/y%2)    cout << "YES" << endl;
    else    cout << "NO" << endl;
    return 0;
}
View Code

B.分4种情况分别计算。

#include<bits/stdc++.h>
using namespace std;

int n,a[100005];

int main()
{
    ios::sync_with_stdio(0);
    cin >> n;
    for(int i = 1;i <= n;i++)   cin >> a[i];
    sort(a+1,a+1+n);
    int num = 1,cnt = 0;
    if(a[2] != a[1])    num++;
    if(a[3] != a[2])    num++;
    if(num == 1)
    {
        for(int i = 1;i <= n;i++)
        {
            if(a[i] == a[1])    cnt++;
        }
        cout << (long long)cnt*(cnt-1)*(cnt-2)/6 << endl;
    }
    else if(num == 2 && a[2] != a[1])
    {
        for(int i = 1;i <= n;i++)
        {
            if(a[i] == a[2])    cnt++;
        }
        cout << (long long)cnt*(cnt-1)/2 << endl;
    }
    else
    {
        for(int i = 1;i <= n;i++)
        {
            if(a[i] == a[3])    cnt++;
        }
        cout << cnt << endl;
    }
    return 0;
}
View Code

C.若x符合,则x+1肯定符合,可以二分最小的x。

#include<bits/stdc++.h>
using namespace std;

long long n,s;

bool ok(long long x)
{
    long long t = x;
    while(t)
    {
        x -= t%10;
        t /= 10;
    }
    if(x >= s)  return 1;
    return 0;
}

int main()
{
    ios::sync_with_stdio(0);
    cin >> n >> s;
    long long l = 1,r = n+1;
    while(l < r)
    {
        long long mid = (l+r)/2;
        if(ok(mid)) r = mid;
        else    l = mid+1;
    }
    cout << n-l+1 << endl;
    return 0;
}
View Code

D.l[i]表示i坐标第一个大于等于a[i]的位置,r[i]表示r右边第一个大于a[i]的位置,这样a[i]被当作max算的次数可以求出。减min只要把每个位置的数取负做相同操作。

#include<bits/stdc++.h>
using namespace std;

int n,a[1000005],l[1000005],r[1000005];
long long ans = 0;

void f()
{
    for(int i = 1;i <= n;i++)
    {
        l[i] = i-1;
        while(l[i] >= 1 && a[i] > a[l[i]])  l[i] = l[l[i]];
    }
    for(int i = n;i >= 1;i--)
    {
        r[i] = i+1;
        while(r[i] <= n && a[i] >= a[r[i]]) r[i] = r[r[i]];
    }
    for(int i = 1;i <= n;i++)
        ans += (long long)(r[i]-i)*(i-l[i])*a[i];
}

int main()
{
    ios::sync_with_stdio(0);
    cin >> n;
    for(int i = 1;i <= n;i++)   cin >> a[i];
    f();
    for(int i = 1;i <= n;i++)   a[i] = -a[i];
    f();
    cout << ans << endl;
    return 0;
}
View Code

E.01异或trie树,把每个数按位分。

#include<bits/stdc++.h>
using namespace std;

int n,tr[2000005][2] = {0},cnt[2000005],sz = 0;

void add(int x,int v)
{
    int now = 0;
    for(int i = 30;i >= 0;i--)
    {
        int t = bool((1<<i)&x);
        if(!tr[now][t]) tr[now][t] = ++sz;
        now = tr[now][t];
        cnt[now] += v;
    }
}

int getsum(int x,int y)
{
    int now = 0,ans = 0;
    for(int i = 30;i >= 0;i--)
    {
        int xt = bool((1<<i)&x),yt = bool((1<<i)&y);
        if(!yt && !tr[now][xt]) break;
        if(!yt) now = tr[now][xt];
        else
        {
            if(tr[now][xt])  ans += cnt[tr[now][xt]];
            if(!tr[now][!xt])   break;
            now = tr[now][!xt];
        }
    }
    return ans;
}

int main()
{
    ios::sync_with_stdio(0);
    cin >> n;
    while(n--)
    {
        int x,y,z;
        cin >> x >> y;
        if(x == 1)  add(y,1);
        else if(x == 2) add(y,-1);
        else
        {
            cin >> z;
            cout << getsum(y,z) << endl;
        }
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zhurb/p/7248026.html