2018-2019 ICPC, NEERC, Northern Eurasia Finals(F,K)

版权声明:http://blog.csdn.net/Mitsuha_。 https://blog.csdn.net/Mitsuha_/article/details/84761942

2018-2019 ICPC, NEERC, Northern Eurasia Finals

在此附上题解

Problem F:Fractions
思路:看懂题意之后,相当于求解 x 1 n + x 2 n + x 3 n + + x k n = n 1 n \frac {x_1}{n}+\frac {x_2}{n}+\frac {x_3}{n}+\dots +\frac {x_k}{n}=\frac {n-1}{n} 其中 g c d ( x i , n ) > 1 gcd(x_i,n)>1
这下不了手,然后发现很多数只需要2项即可凑出来,大胆猜了一发。
如果只有2项的话,则是 x b + y a = n 1 n \frac {x}{b}+\frac{y}{a}=\frac{n-1}{n}
其中 a b = n a*b=n ,然后就是求 a x + b y = n 1 ax+by=n-1 的正整数解了,用扩展欧几里德即可。

#include<bits/stdc++.h>
using namespace std;
const int MOD=1e9+7;
const int MAX=2e5+10;
const double PI=acos(-1.0);
typedef long long ll;
ll gcd(ll x,ll y){return y==0?x:gcd(y,x%y);}
void exgcd(ll a,ll b,ll &x,ll&y)
{
    if(b==0){x=1;y=0;}
    else
    {
        exgcd(b,a%b,y,x);
        y-=x*(a/b);
    }
}
int main()
{
    ll n;
    cin>>n;
    for(ll i=2;i*i<=n;i++)
    {
        if(n%i==0)
        {
            ll a=i;
            ll b=n/i;
            ll g=gcd(a,b);
            if((n-1)%g)continue;
            ll x,y;
            exgcd(a,b,x,y);
            x=(x+b/g)*((n-1)/g);
            x=(x%(b/g)+b/g)%(b/g);
            y=(n-1-a*x)/b;
            printf("YES\n2\n");
            printf("%lld %lld\n",x/gcd(x,b),b/gcd(x,b));
            printf("%lld %lld\n",y/gcd(y,a),a/gcd(y,a));
            return 0;
        }
    }
    puts("NO");
    return 0;
}

Problem K:King Kog’s Reception

思路:对于一个区间 [ L , R ] [L,R] 来说,假设这个区间内所有骑士的 d d 的值加起来为 s u m [ L ] [ R ] sum[L][R] ,若 s u m [ L ] [ R ] ( R L ) &gt; 0 sum[L][R]-(R-L)&gt;0 ,很明显,骑士最后结束见面的时间是会超出这个区间的,且超出的时间 t i m e = s u m [ L ] [ R ] ( R L ) time=sum[L][R]-(R-L)

那么对于每个询问 t t ,我们就是要找到最大的 t i m e time
t i m e = m a x ( s u m [ i ] [ t ] ( t i ) ) time=max(sum[i][t]-(t-i)) t i m e = m a x ( s u m [ i ] [ t ] + i t ) , ( 1 i t ) time=max(sum[i][t]+i-t),(1\le i\le t)
然后就需要用数据结构来维护 s u m [ i ] [ t ] + i sum[i][t]+i 了。

#include<bits/stdc++.h>
using namespace std;
const int MOD=998244353;
const int MAX=1e6+10;
const double PI=acos(-1.0);
typedef long long ll;
int X[MAX],Y[MAX];
struct lenka
{
    int l,r;
    ll ma,tag;
}A[MAX<<2];
void build(int k,int l,int r)
{
    A[k].l=l,A[k].r=r;
    A[k].ma=l;
    if(l==r)return;
    build(2*k,l,(l+r)/2);
    build(2*k+1,(l+r)/2+1,r);
    A[k].ma=max(A[2*k].ma,A[2*k+1].ma);
}
void add(int k,int x,int y,ll z)
{
    if(x==A[k].l&&y==A[k].r)
    {
        A[k].tag+=z;
        A[k].ma+=z;
        return;
    }
    if(A[k].tag)
    {
        add(2*k,A[2*k].l,A[2*k].r,A[k].tag);
        add(2*k+1,A[2*k+1].l,A[2*k+1].r,A[k].tag);
        A[k].tag=0;
    }
    if(y<=A[2*k].r)add(2*k,x,y,z);
    else if(x>=A[2*k+1].l)add(2*k+1,x,y,z);
    else
    {
        add(2*k,x,A[2*k].r,z);
        add(2*k+1,A[2*k+1].l,y,z);
    }
    A[k].ma=max(A[2*k].ma,A[2*k+1].ma);
}
ll askma(int k,int x,int y)
{
    if(x==A[k].l&&y==A[k].r)return A[k].ma;
    if(A[k].tag)
    {
        add(2*k,A[2*k].l,A[2*k].r,A[k].tag);
        add(2*k+1,A[2*k+1].l,A[2*k+1].r,A[k].tag);
        A[k].tag=0;
    }
    if(y<=A[2*k].r)return askma(2*k,x,y);
    if(x>=A[2*k+1].l)return askma(2*k+1,x,y);
    return max(askma(2*k,x,A[2*k].r),askma(2*k+1,A[2*k+1].l,y));
}
ll BIT[MAX];
void add(int x,int y){while(x<=1000000){BIT[x]+=y;x+=x&(-x);}}
ll ask(int x){ll tot=0;while(x){tot+=BIT[x];x-=x&(-x);}return tot;}
int main()
{
    build(1,1,1000000);
    int T;
    cin>>T;
    for(int i=1;i<=T;i++)
    {
        char s[4];
        scanf("%s",s);
        if(s[0]=='+')
        {
            scanf("%d%d",&X[i],&Y[i]);
            add(1,1,X[i],Y[i]);
            add(X[i],Y[i]);
        }
        if(s[0]=='-')
        {
            scanf("%d",&X[i]);
            add(1,1,X[X[i]],-Y[X[i]]);
            add(X[X[i]],-Y[X[i]]);
        }
        if(s[0]=='?')
        {
            scanf("%d",&X[i]);
            printf("%lld\n",askma(1,1,X[i])-X[i]-(ask(1000000)-ask(X[i])));
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Mitsuha_/article/details/84761942