1. 程式人生 > >Codeforces 水題選刷

Codeforces 水題選刷

翻譯會給出在程式碼中

Ctrl+F點開網頁搜尋,直接查題號即可

有一些很棒的題我會單獨拿出來寫題解的,特別水的題就不做了嘻嘻嘻

Codeforces 938C

/*
題解:
給定兩個正整數n,m(m≤n),對於一個n階0-1方陣,
其任意m階子方陣中至少有一個元素“0”,則可以求解這個方陣中的“1”的最大數目。現求解這個問題的逆向問題:已知這個最大數目為X,求相應的n和m。 
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; int n,m; int main() { int T;scanf("%d",&T); while(T--) { int x;scanf("%d",&x); if(x==0){printf("1 1\n");continue;} bool bk=false; for(int i=1;i*i<=x;i++) { int j=x/i; if(i*j==x && ((i&1
)==(j&1))) { n=(i+j)/2; int temp=n-i; if(temp==0)continue; m=n/temp; if(n>=m && (n/m)==temp) { printf("%d %d\n",n,m); bk=true; break
; } } } if(bk==false)printf("-1\n"); } return 0; }

Codeforces 938D

/*
翻譯:
給定一張包含n(n<=2*10^5)個節點的圖,給出m(m<=2*10^5)條雙向邊,邊有權,每個點也有權
對於每個點i,你要輸出i到任意一個點再回來的最小代價,到達那個點時要加入那個點的點權,經過則不用 
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
typedef long long LL;
LL d[210000];
struct pt
{
    int x;
    friend bool operator <(pt n1,pt n2){return d[n1.x]>d[n2.x];}
};
priority_queue<pt> q;
inline LL read()
{
    LL f=1,x=0;char ch=getchar();
    while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
struct node
{
    LL c;
    int x,y,next;
}a[810000];int len,last[210000];
void ins(int x,int y,LL c)
{
    len++;
    a[len].x=x;a[len].y=y;a[len].c=c;
    a[len].next=last[x];last[x]=len;
}
int n,m,st;
bool v[210000];
int main()
{
    n=read();m=read();st=n+1;
    len=0;memset(last,0,sizeof(last));
    for(int i=1;i<=m;i++)
    {
        int x=read(),y=read();LL c=read();
        ins(x,y,2*c);ins(y,x,2*c);
    }
    for(int i=1;i<=n;i++)
    {
        LL x=read();
        ins(st,i,x);
    }
    memset(d,63,sizeof(d));d[st]=0;
    memset(v,false,sizeof(v));v[st]=true;
    pt tmp;tmp.x=st;q.push(tmp);
    while(!q.empty())
    {
        tmp=q.top();int x=tmp.x;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(d[y]>d[x]+a[k].c)
            {
                d[y]=d[x]+a[k].c;
                if(v[y]==false)
                {
                    v[y]=true;
                    pt cnt;cnt.x=y;q.push(cnt);
                }
            }
        }
        q.pop();v[x]=false;
    }
    for(int i=1;i<n;i++)printf("%lld ",d[i]);
    printf("%lld\n",d[n]);
    return 0;
}

Codeforces 939E

/*
翻譯:
給出Q(Q<=5*10^5)個操作,共有兩種操作
第一種操作輸入兩個數op x:op表示第幾種操作,x表示在當前序列中插入數x(x<=10^9),保證x大於當前序列中任意一個數
第二種操作輸入一個數op:op表示第幾種操作,求當前序列中的Maximize
定義Maximize為:在當前序列中找出一個子集,Maximize表示子集中數最大值/子集平均數的最大值
輸出保留10位小數 
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
LL sum[510000],f[510000],list[510000];
int T,head;
int main()
{
    head=0;
    scanf("%d",&T);
    while(T--)
    {
        int op;LL x;
        scanf("%d",&op);
        if(op==1)
        {
            scanf("%I64d",&list[++head]);
            sum[head]=sum[head-1]+list[head];
        }
        else
        {
            int l=1,r=head;
            while(l<r-1)
            {
                int mid=(l+r)/2;
                int mmid=(mid+r)/2;
                if((double)(list[head]+sum[mid])/(mid+1)>(double)(list[head]+sum[mmid])/(mmid+1))l=mid;
                else r=mmid;
            }
            if((double)(list[head]+sum[l])/(l+1)>(double)(list[head]+sum[r])/(r+1))printf("%.10lf\n",(double)list[head]-(double)(list[head]+sum[r])/(r+1));
            else printf("%.10lf\n",(double)list[head]-(double)(list[head]+sum[l])/(l+1));
        }
    }
    return 0;
}

Codeforces 940F

/*
翻譯: 
給出一個長度為n(n<=100000)的序列,序列中每個數a[i]<=10^9
設c[i]表示第i種數出現的次數 
q(q<=100000)次詢問,詢問共有兩種
第一種 1 x y 表示求序列中x~y c[i]的mex。mex表示最小的沒有出現過的值(不包括0) 
第二種 2 x y 表示把序列中第x位的數替換為y 
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
map<int,int> q;
int val[210000],len;
int l,r,t;
struct pck{int p,c,las;}ch[210000];int chlen;
struct ask
{
    int l,r,t,op;
}A[210000];int n,m,alen;
int block,pos[210000];
bool cmp(ask n1,ask n2)
{
    if(pos[n1.l]!=pos[n2.l])return pos[n1.l]<pos[n2.l];
    if(pos[n1.r]!=pos[n2.r])return pos[n1.r]<pos[n2.r];
    return n1.t<n2.t;
}
int vis[210000];//sum[i]的出現次數 
int col[210000],las[210000],answer[210000],ans;//las[i]表示第i個位置上一次的顏色 
int sum[210000];//每種數出現了多少次 
void upd_col(int now,int c)
{
    if(now>=l && now<=r)vis[sum[col[now]]]--,sum[col[now]]--,vis[sum[col[now]]]++;
    col[now]=c;
    if(now>=l && now<=r)vis[sum[col[now]]]--,sum[col[now]]++,vis[sum[col[now]]]++;
}
void del(int now)
{
    vis[sum[col[now]]]--;
    sum[col[now]]--;
    vis[sum[col[now]]]++;
}
void add(int now)
{
    vis[sum[col[now]]]--;
    sum[col[now]]++;
    vis[sum[col[now]]]++;
}
int gtans(){for(int i=1;;i++)if(vis[i]==0)return i;}
int main()
{
    scanf("%d%d",&n,&m);
    block=ceil(pow(n,2.0/3));
    for(int i=1;i<=n;i++)pos[i]=(i-1)/block+1;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&col[i]);
        val[++len]=col[i];las[i]=col[i];
    }
    for(int i=1;i<=m;i++)
    {
        int op,u,v;
        scanf("%d%d%d",&op,&u,&v);
        if(op==1)
        {
            alen++;
            A[alen].l=u;A[alen].r=v;A[alen].t=chlen;
            A[alen].op=i-chlen;
        }
        else
        {
            chlen++;ch[chlen].p=u;ch[chlen].c=v;
            ch[chlen].las=las[u];las[u]=v;
            val[++len]=v;
        }
    }
    sort(val+1,val+1+len);
    len=unique(val+1,val+1+len)-val-1;
    for(int i=1;i<=len;i++)q[val[i]]=i;
    for(int i=1;i<=chlen;i++)ch[i].las=q[ch[i].las],ch[i].c=q[ch[i].c];
    for(int i=1;i<=n;i++)col[i]=q[col[i]];
    sort(A+1,A+1+alen,cmp);
    l=A[1].l,r=A[1].r,t=A[1].t;
    for(int i=1;i<=A[1].t;i++)col[ch[i].p]=ch[i].c;
    for(int i=A[1].l;i<=A[1].r;i++)
    {
        vis[sum[col[i]]]--;
        sum[col[i]]++;
        vis[sum[col[i]]]++;
    }
    for(int i=1;;i++)if(vis[i]==0){answer[A[1].op]=i;break;}
    for(int i=2;i<=alen;i++)
    {
        while(t<A[i].t)t++,upd_col(ch[t].p,ch[t].c);
        while(t>A[i].t)upd_col(ch[t].p,ch[t].las),t--;
        while(l<A[i].l)del(l++);
        while(l>A[i].l)add(--l);
        while(r<A[i].r)add(++r);
        while(r>A[i].r)del(r--);
        answer[A[i].op]=gtans();
        //for(int j=l;j<=r;j++)printf("%d ",col[j]);
    }
    for(int i=1;i<=alen;i++)printf("%d\n",answer[i]);
    return 0;
}

Codeforces 946D

/*
翻譯:
定義一個星期n(n<=500)天,一天m(m<=500)個小時。給定課表,你想翹課,但最多隻能翹K(K<=500)節課
定義一天在學校的時間為(該天最後一節課時間-該天第一節課時間+1)
你想要這個星期呆在學校的時間儘量短,求這個最短時間 
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
char ch[510][510];
int sum[510][510];//第i天 翹j節課 
int f[510][510];//前i天 翹j節課 
int n,m,K,a[510],s[510],gt[510];
int pre[510];
int main()
{
    scanf("%d%d%d",&n,&m,&K);
    for(int i=1;i<=n;i++)
    {
        int cnt=0;
        scanf("%s",ch[i]+1);
        for(int j=1;j<=m;j++)a[j]=ch[i][j]-'0';
        for(int j=1;j<=m;j++){if(a[j]==1)gt[++cnt]=j,s[i]++;}
        if(cnt!=0)sum[i][0]=m-(gt[cnt]-gt[1]+1);
        else {sum[i][0]=m;continue;}
        for(int j=1;j<=s[i];j++)//翹多少節課 
        {
            if(j==s[i]){sum[i][j]=m;break;}
            int u=s[i]-j;//上多少節課 
            for(int k=1;k<=cnt-u+1;k++)
                sum[i][j]=max(sum[i][j],m-(gt[k+u-1]-gt[k]+1));
        }
    }
    f[0][0]=0;
    for(int i=1;i<=n;i++)
        for(int j=0;j<=K;j++)
            for(int k=0;k<=min(K,s[i]);k++)
            {
                if(j>=k)f[i][j]=max(f[i-1][j-k]+sum[i][k],f[i][j]);
            }
    printf("%d\n",n*m-f[n][K]);
    return 0;
}

Codeforces 946E

/*
翻譯:
定義一個數為美麗數,當且僅當這個數長度為偶數,且他的某一個排列可以組成一個迴文數
給出n(n<=2*10^100000),求小於n的最大美麗數 
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
char ch[210000];
int a[210000],g[15],len;
int f[210000][10];
void sol()
{
    for(int i=len;i>=1;i--)
        for(int j=a[i]-1;j>=0;j--)
        {
            if(i==1 && j==0)break;
            int cnt=0,maxx=0;
            for(int k=0;k<=9;k++)
            {
                int op=0;if(k==j)op=1;
                if(f[i-1][k]^op==1)cnt++,maxx=k;
            }
            if(len-i<cnt)continue;
            for(int k=1;k<=i-1;k++)printf("%d",a[k]);
            printf("%d",j);
            for(int k=i+1;k<=len-cnt;k++)printf("9");
            int t=maxx;
            for(int k=len-cnt+1;k<=len;k++)
            {
                int op=0;if(t==j)op=1;else op=0;
                while(f[i-1][t]^op!=1){t--;if(t==j)op=1;else op=0;}
                printf("%d",t);t--;
            }
            printf("\n");
            return ;
        }
    for(int i=1;i<len-2;i++)printf("9");
    printf("\n");
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(g,0,sizeof(g));
        scanf("%s",ch+1);len=strlen(ch+1);
        for(int i=1;i<=len;i++)a[i]=ch[i]-'0',g[a[i]]++;
        if(len%2==1)
        {
            for(int i=1;i<len;i++)printf("9");
            printf("\n");continue;
        }
        if((g[1]==1 && g[0]==len-1 && a[1]==1) || (g[1]==2 && g[0]==len-2 && a[1]==1 && a[len]==1))
        {
            for(int i=1;i<len-1;i++)printf("9");
            printf("\n");continue;
        }
        for(int i=0;i<=9;i++)f[0][i]=0;//0 偶數次
        for(int i=1;i<=len;i++)
            for(int j=0;j<=9;j++)
            {
                if(a[i]==j)f[i][j]=f[i-1][j]^1;
                else f[i][j]=f[i-1][j];
            }
        sol();
    }
    return 0;
}

Codeforces 946F

/*
翻譯: 
定義f[i]=f[i-1]+f[i-2],+表示拼接的意思,即為f[i-1]與f[i-2]拼接起來組成f[i]
給出一個子串(長度<=100),求這個子串在fn(n<=100)的**子序列**中出現了多少次
答案對1e9+7取模
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const LL mod=1e9+7;
LL f[110][110][110];
LL lenth[110];//新增2^lenth[i]次方個數 
char ch[110];int n,m;
int main()
{
    scanf("%d%d",&n,&m);
    scanf("%s",ch+1);
    for(int i=1;i<=n;i++)f[ch[i]-'0'][i][i]=1;
    lenth[0]=lenth[1]=2;
    for(int i=2;i<=m;i++)lenth[i]=(lenth[i-1]*lenth[i-2])%mod;
    for(int i=2;i<=m;i++)
        for(int l=1;l<=n;l++)
            for(int r=l;r<=n;r++)
            {
                LL opx,opy;
                if(l==1)opx=lenth[i-1];else opx=1;
                if(r==n)opy=lenth[i-2];else opy=1;
                f[i][l][r]=(f[i][l][r]+(opx*f[i-2][l][r]+opy*f[i-1][l][r])%mod)%mod;
                for(int k=l;k<r;k++)
                    f[i][l][r]=(f[i][l][r]+f[i-1][l][k]*f[i-2][k+1][r])%mod;
            }
    printf("%lld\n",f[m][1][n]);
    return 0;
}

Codeforces 946G

/*
翻譯:
給出一個長度為n(n<=10^5)的序列,要求最少的次數,使得序列變為一個刪去一個數後嚴格上升的序列 
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
int f[2][210000];//沒刪  刪 
int n,pos,ans;
int main()
{
    scanf("%d",&n);
    memset(f,63,sizeof(f));
    f[0][0]=-1e9;
    for(int i=1;i<=n;i++)
    {
        int x;scanf("%d",&x);
        int t=upper_bound(f[1]+1,f[1]+1+n,x-i+1)-f[1];
        f[1][t]=x-i+1;ans=max(ans,t);
        f[1][pos]=min(f[1][pos],f[0][pos]);ans=max(ans,pos);
        t=upper_bound(f[0]+1,f[0]+1+n,x-i)-f[0];
        f[0][pos=t]=x-i;
    }
    printf("%d\n",max(0,n-ans-1));
    return 0;
}

Codeforces 950B

/*
翻譯:
給出兩個數字串a,b,長度分別為n,m(n,m<=10^6)
求之多能把a,b分成多少部分,使得每一部分分別相等 
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
int a[1100000],b[1100000];
int n,m;
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=m;i++)scanf("%d",&b[i]);
    int i=0,j=0,sx=0,sy=0,ans=0;
    while(i+1<=n && j+1<=m)
    {
        i++;j++;
        sx+=a[i];sy+=b[j];
        while(sx!=sy)
        {
            if(sx<sy)sx+=a[++i];
            else sy+=b[++j];
        }
        ans++;sx=sy=0;
    }
    printf("%d\n",ans);
    return 0;
}

Codeforces 954A

/*
給定一段長度為n(n<=100)的字串,R與U可以組合在一起,求組合在一起後最短字串長度 
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
char ch[110];
int main()
{
    int n;
    scanf("%d",&n);
    scanf("%s",ch+1);
    int i=1,cnt=0;
    while(i<=n)
    {
        if((ch[i]=='R' && ch[i+1]=='U') || (ch[i]=='U' && ch[i+1]=='R'))cnt++,i+=2;
        else cnt++,i+=1;
    }
    printf("%d\n",cnt);
    return 0;
}

Codeforces 954B

/*
翻譯:
給定一個字串,每次可以輸入1個字元(低端操作)或進行之多一次高階操作
高階操作:複製當前字串並插入至當前字串末尾
求可以弄出這個字串的最小總運算元 
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
char ch[110];
int n;
int main()
{
    scanf("%d",&n);
    scanf("%s",ch+1);
    int ans=n;
    for(int i=1;i<=n;i++)
    {
        bool bk=false;
        for(int j=i+1;j<=i+i;j++)if(ch[j]!=ch[j-i]){bk=true;break;}
        if(bk==false)ans=min(ans,n-2*i+1+i);
    }
    printf("%d\n",ans);
    return 0;
}

Codeforces 954C

/*
翻譯:
定義一個矩陣u*v由1~u*v組成,位置(i,j)填值(i-1)*v+j。每個格子可以向上下左右走(邊界你懂得)
給出一段路線,判斷這條路線是否可以在某一個矩陣中走出。不能輸出NO,能則輸出YES以及某個矩陣的u,v 
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
int n;
int a[210000];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        if(i==1)continue;
        if(a[i]==a[i-1]){printf("NO\n");return 0;}
    }
    if(n==1)
    {
        printf("YES\n1 %d\n",a[1]);
        return 0;
    }
    int x,y,t=1,sx=-1,sy=-1;
    for(int i=2;i<=n;i++)if(abs(a[i]-a[i-1])!=1){sy=abs(a[i]-a[i-1]);break;}
    if(sy==-1)
    {
        int maxx=0;
        for(int i=1;i<=n;i++)maxx=max(maxx,a[i]);
        printf("YES\n1 %d\n",maxx);
        return 0;
    }
    x=(a[1]-1)/sy+1;y=(a[1]-1)%sy+1;
    sx=max(sx,x);
    bool bk=false;
    while(t<=n)
    {
        t++;if(t>n)break;
        if(a[t]==a[t-1]+1)
        {
            if(sy==-1 || y<sy)y++;
            else{bk=true;break;}
        }
        else if(a[t]==a[t-1]-1)
        {
            if(y==1){bk=true;break;}
            else y--;
        }
        else
        {
            if(a[t]>a[t-1])
            {
                int tmp=a[t]-a[t-1];
                if(sy==-1 || sy==tmp)sy=tmp;
                else {bk=true;break;}
                x++;
            }
            else
            {
                int tmp=a[t-1]-a[t];
                if(sy==-1 || sy==tmp)sy=tmp;
                else {bk=true;break;}
                x--;
                if(x==0){bk=true;break;}
            }
        }
        sx=max(sx,x);
    }
    if(bk==true || (sx>1e9 || sy>1e9))printf("NO\n");
    else printf("YES\n%d %d\n",sx,sy);
    return 0;
}

Codeforces 954D

/*
翻譯:
給出一張圖,點數n(n<=1000),邊數m(m<=1000)。
給出兩個點s,t,要在圖內新增一條邊並保證s->t的最短路徑長度不改變
求這樣的邊有多少條 
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
struct node
{
    int x,y,next;
}a[2100];int len,last[1100];
void ins(int x,int y)
{
    len++;
    a[len].x=x;a[len].y=y;
    a[len].next=last[x];last[x]=len;
}
int n,m,stx,sty;
bool v[1100];
int d[2][1100],list[1100],head,tail,st;
void spfa(int op)
{
    memset(v,false,sizeof(v));v[st]=true;
    memset(d[op],63,sizeof(d[op]));d[op][st]=0;
    list[1]=st;head=1;tail=2;
    while(head!=tail)
    {
        int x=list[head];
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(d[op][y]>d[op][x]+1)
            {
                d[op][y]=d[op][x]+1;
                if(v[y]==false)
                {
                    v[y]=true;
                    list[tail++]=y;
                    if(tail==n+1)tail=1;
                }
            }
        }
        head++;if(head==n+1)head=1;
        v[x]=false;
    }
}
bool mp[1100][1100];
int main()
{
    scanf("%d%d%d%d",&n,&m,&stx,&sty);
    memset(mp,false,sizeof(mp));len=0;memset(last,0,sizeof(last));
    for(int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);mp[x][y]=mp[y][x]=true;
        ins(x,y);ins(y,x);
    }
    st=stx;spfa(0);
    st=sty;spfa(1);
    int ans=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)if(i!=j && mp[i][j]==false)
        {
            mp[i][j]=mp[j][i]=true;
            if(d[0][i]+d[1][j]+1>=d[0][sty] && d[0][j]+d[1][i]+1>=d[0][sty])ans++;
        }
    printf("%d\n",ans);
    return 0;
}

Codeforces 954E

/*
翻譯:
給定n(n<=2*10^5)個水龍頭,第i個水龍頭有最大出水量a[i](a[i]<=10^6),且給定一個溫度值t[i](t[i]<=10^6)。
定義一次出水得到的溫度為Sigma(a[i]*t[i])/Sigama(a[i]),給定一次出水得到的溫度,求最大總出水量。
如果得不到該溫度,輸出0 
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
int n,T;
struct node
{
    LL a,t;
}P[1110000];
bool cmp(node n1,node n2){return n1.t<n2.t;}
int main()
{
    scanf("%d%d",&n,&T);
    for(int i=1;i<=n;i++)scanf("%lld",&P[i].a);
    for(int i=1;i<=n;i++)scanf("%lld",&P[i].t);
    LL sx=0,sy=0,ax=0,ay=0;
    for(int i=1;i<=n;i++)
    {
        if(P[i].t>T)sx+=P[i].a*(P[i].t-T),ax+=P[i].a;
        else if(P[i].t<T)sy+=P[i].a*(T-P[i].t),ay+=P[i].a;
    }
    double ans=0;LL sum=0;
    if(sx<sy)//負的多 
    {
        ans=(double)ax;sum=sx;
        sort(P+1,P+1+n,cmp);
        int tmp=n;
        for(int i=1;i<=n;i++)if(P[i].t>=T){tmp=i-1;break;}
        for(int i=tmp;i>=1;i--)
        {
            if(sum-P[i].a*(T-P[i].t)>0)sum-=P[i].a*(T-P[i].t),ans+=(double)P[i].a;
            else
            {
                ans+=(double)sum/(T-P[i].t);
                sum=0;
                break;
            }
        }
        for(int i=1;i<=n;i++)if(P[i].t==T)ans+=(double)P[i].a;
        if(sum==0)printf("%.15lf\n",ans);
        else printf("0\n");
    }
    else
    {
        ans=(double)ay;sum=sy;
        sort(P+1,P+1+n,cmp);
        int tmp=1;
        for(int i=n;i>=1;i--)if(P[i].t<=T){tmp=i+1;break;}
        for(int i=tmp;i<=n;i++)
        {
            if(sum-P[i].a*(P[i].t-T)>0)sum-=P[i].a*(P[i].t-T),ans+=(double)P[i].a;
            else
            {
                ans+=(double)sum/(P[i].t-T);
                sum=0;
                break;
            }
        }
        for(int i=1;i<=n;i++)if(P[i].t==T)ans+=(double)P[i].a;
        if(sum==0)printf("%.15lf\n",ans);
        else printf("0\n");
    }
    return 0;
}

Codeforces 954F

/*
翻譯:
給定一個3行m(m<=10^18)列的矩陣,從格子(i,j)可以移到(i,j+1)與(i-1(i>1),j+1),(i+1(i<3),j+1)
矩陣內會存在n個位於a[i]行,座標l[i]~r[i]的障礙物,障礙物不能通行
求從格子(2,1)移動至(2,m)的方案數,答案對1e9+7取模 
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const LL mod=1e9+7;
struct node
{
    LL l,r;int a;
}P[11000];
LL s[21000];
int t,c[5][41000],pre[5];
int n;LL m;
struct matrix
{
    LL m[5][5