多校冲刺 noip 11.04

多校冲刺 noip 11.04

今天挂大分!!我不嘚。。。

所以我啥时候可以把情况考虑完全啊!!

啥时候可以随出来把我程序卡掉的数据啊!!

T1 谜之阶乘

这题随便做就能切,真的随便做......

AC_code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=1e6+5;
int T,n,mx=1e18;
int cx[22][N],dy[22][N];
int cnt[23],c,ans[30][2];
signed main(){
    freopen("factorial.in","r",stdin);
    freopen("factorial.out","w",stdout);
    // cout<<(sizeof(cx)*3>>20)<<endl;
    fo(i,4,1000001){
        int now=i*(i-1);
        fu(j,i-2,2){
            if(now>mx/j)break;
            now*=j;
            cx[i-j+1][++cnt[i-j+1]]=now;
            dy[i-j+1][cnt[i-j+1]]=i;
        }
    }
    scanf("%lld",&T);
    while(T--){
        scanf("%lld",&n);
        if(n==1){printf("-1\n");continue;}
        c=1;ans[1][0]=n;ans[1][1]=n-1;
        int sq=sqrt(n);if(n!=2&&sq*(sq+1)==n)ans[++c][0]=sq+1,ans[c][1]=sq-1;
        fo(i,3,20){
            int pos=lower_bound(cx[i]+1,cx[i]+cnt[i]+1,n)-cx[i];
            if(cx[i][pos]==n)ans[++c][0]=dy[i][pos],ans[c][1]=dy[i][pos]-i;
        }
        printf("%lld\n",c);
        fu(i,c,1)printf("%lld %lld\n",ans[i][0],ans[i][1]);
    }
    return 0;
}

T2 子集

这个我找的规律好像不太好形容,所以看代码吧

考场上因为不会用官方给的\(checker\),于是自己写了一个.....

checker
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=1e6+5;
int T,n,k;
int vis[N];
signed main(){
    FILE *f1=fopen("subset.in","r");
    FILE *f2=fopen("subset.out","r");
    FILE *f3=fopen("b.ans","w");
    fscanf(f1,"%lld",&T);
    fo(t,1,T){
        fscanf(f1,"%lld%lld",&n,&k);
        fo(i,1,n)vis[i]=false;
        char s[10];fscanf(f2,"%s",s+1);
        if(s[1]=='N')continue;
        fo(i,1,k){
            int sum=0;
            fo(j,1,n/k){
                int x;fscanf(f2,"%lld",&x);
                if(vis[x]||x>n){fprintf(f3,"WA on test %lld ",t);return 0;}
                sum+=x;vis[x]=true;
            }
            if(sum!=(n*(n+1))/2/k){fprintf(f3,"WA on test %lld ",t);return 0;}
        }
    }
    fprintf(f3,"AC");
    return 0;
}
AC_code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=1e6+5;
int T,n,k;
int odd[N][3];
void get_odd(int x){
    int mx=x*3;
    odd[1][0]=1;
    odd[1][1]=(mx>>1)+1;
    odd[1][2]=mx;
    fo(i,2,x){
        if(odd[i-1][1]+1==odd[i-1][2]){
            odd[i][0]=odd[i-1][0]+1;
            odd[i][1]=(((mx>>1)-i+1)>>1)+odd[i][0];
            odd[i][2]=mx-1;
            continue;
        }
        odd[i][0]=odd[i-1][0]+1;
        odd[i][1]=odd[i-1][1]+1;
        odd[i][2]=odd[i-1][2]-2;
    }
}
signed main(){
    freopen("subset.in","r",stdin);
    freopen("subset.out","w",stdout);
    scanf("%lld",&T);
    while(T--){
        scanf("%lld%lld",&n,&k);
        if(n==1&&k==1){printf("Yes\n1\n");continue;}
        int sum=n*(n+1)/2,num;
        if(sum%k!=0||sum/k<n){printf("No\n");continue;}
        printf("Yes\n");num=n/k;
        if(num&1){
            get_odd(k);
            int s=k*3+1,t=n;
            fo(i,1,k){
                printf("%lld %lld %lld ",odd[i][0],odd[i][1],odd[i][2]);
                fo(i,4,num){
                    if(i&1)printf("%lld ",s),s++;
                    else printf("%lld ",t),t--;
                }
                printf("\n");
            }
        }
        else {
            int s=1,t=n;
            fo(i,1,k){
                fo(i,1,num){
                    if(i&1)printf("%lld ",s),s++;
                    else printf("%lld ",t),t--;
                }
                printf("\n");
            }
        }
    }
    return 0;
}

T3 混凝土粉末

这个题应该是个套路吧,只是我没有见过,然后智商有点低,就没有想出来

首先我们知道,如果某一次放沙子对某一次询问有贡献

我们需要保证两个条件:

第一个是空间上,修改必须覆盖询问

第二个是时间上,修改必须在询问前面

我们发现这个题意可以转化为,询问\(x\)位置上高度大于\(y\)的最早时间

这样转化完之后,很容易发现可以用二分,但是需要下面的维护

发现二分需要区间可加性,但是我们所说的空间是区间不可加的

所以我们扫描空间,用线段树维护时间

我们对于每一个询问,在基岩轴的左端点加上高度,右端点减去高度

每一个询问,我们也可以将它放到基岩轴上去,可以直接在线段树上二分

线段树维护的是时间轴

我们直接扫描这个基岩轴

遇到需要加的就在线段树上对应的时间处加上,减去一样

查询直接在询问的时间左边二分就好了

AC_code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=1e6+5;
int n,q;
struct XDS{
    #define ls x<<1
    #define rs x<<1|1
    int sum[N*4],res,mx;
    void pushup(int x){
        sum[x]=sum[ls]+sum[rs];
        return ;
    }
    void ins(int x,int l,int r,int pos,int v){
        if(l==r)return sum[x]+=v,void();
        int mid=l+r>>1;
        if(pos<=mid)ins(ls,l,mid,pos,v);
        else ins(rs,mid+1,r,pos,v);
        pushup(x);return ;
    }
    void query(int x,int l,int r,int qr){
        if(~res||l>qr)return ;
        if(r<=qr){
            if(l==r){
                if(sum[x]>=mx)res=l;
                else mx-=sum[x];
                return ;
            }
            int mid=l+r>>1;
            if(sum[ls]<mx)mx-=sum[ls],query(rs,mid+1,r,qr);
            else query(ls,l,mid,qr);
            return ;
        }
        int mid=l+r>>1;
        query(ls,l,mid,qr);
        query(rs,mid+1,r,qr);
        return ;
    }
    #undef ls
    #undef rs
}xds;
vector<pair<int,int> > add[N],del[N],qry[N];
int ans[N];
signed main(){
    freopen("concrete.in","r",stdin);
    freopen("concrete.out","w",stdout);
    scanf("%lld%lld",&n,&q);
    for(int i=1,tp,l,r,h;i<=q;i++){
        scanf("%lld%lld%lld",&tp,&l,&r);
        if(tp==1){ans[i]=-1;
            scanf("%lld",&h);
            add[l].push_back(make_pair(h,i));
            del[r+1].push_back(make_pair(h,i));
        }
        else {
            qry[l].push_back(make_pair(r,i));
        }
    }
    fo(i,1,n){
        for(auto j:add[i])xds.ins(1,1,q,j.second,j.first);
        for(auto j:del[i])xds.ins(1,1,q,j.second,-j.first);
        for(auto j:qry[i]){
            xds.res=-1;xds.mx=j.first;
            xds.query(1,1,q,j.second);
            ans[j.second]=xds.res==-1?0:xds.res;
        }
    }
    fo(i,1,q)if(ans[i]!=-1)printf("%lld\n",ans[i]);
}

T4 排水系统

考场上干傻了,没看见只有一条坏了,直接转移还有\(36pts\)

所以我们可以维护出来每一个位置的期望变化值

因为只有一条边是坏掉的,所以我们就可以先按照没有变化的推一遍

这时候求出来每一个点的变化值

再推一遍,将变化值下放

AC_code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=2e5+5;
const int M=5e5+5;
const int mod=998244353;
int ksm(int x,int y){
    int ret=1;
    while(y){
        if(y&1)ret=ret*x%mod;
        x=x*x%mod;y>>=1;
    }return ret;
}
int n,m,r,k;
int to[M],nxt[M],a[M],head[N],rp;
void add_edg(int x,int y,int z){
    to[++rp]=y;
    a[rp]=z;
    nxt[rp]=head[x];
    head[x]=rp;
}
int sum[N],cd[N],rd[N],du[N],all,inv;
int dp[N];
queue<int> q;
signed main(){
    freopen("water.in","r",stdin);
    freopen("water.out","w",stdout);
    scanf("%lld%lld%lld%lld",&n,&m,&r,&k);
    fo(i,1,k){
        int x,y,z;scanf("%lld%lld%lld",&x,&y,&z);
        add_edg(x,y,z);all=(all+z)%mod;
        cd[x]++;rd[y]++;du[y]++;
    }
    inv=ksm(all,mod-2);
    fo(i,1,m){sum[i]=dp[i]=1;q.push(i);}
    while(!q.empty()){
        int x=q.front();q.pop();
        dp[x]=(dp[x]-sum[x]+mod)%mod;
        int no=0,ys=0;
        for(int i=head[x];i;i=nxt[i]){
            int y=to[i];
            int now=sum[x]*ksm(cd[x]-1,mod-2)%mod*a[i]%mod*inv%mod;
            ys=(ys+now)%mod;no=(no+a[i])%mod;
            dp[y]=(dp[y]-now+mod)%mod;
        }
        no=(all-no+mod)%mod*inv%mod;
        ys=(ys+no*sum[x]%mod*ksm(cd[x],mod-2)%mod)%mod;
        for(int i=head[x];i;i=nxt[i]){
            int y=to[i];rd[y]--;
            dp[y]=(dp[y]+ys)%mod;
            sum[y]=(sum[y]+sum[x]*ksm(cd[x],mod-2))%mod;
            if(!rd[y])q.push(y);
        }
    }
    //fo(i,1,n)cout<<sum[i]<<" "<<dp[i]<<endl;
    fo(i,1,m)q.push(i);
    while(!q.empty()){
        int x=q.front();q.pop();
        for(int i=head[x];i;i=nxt[i]){
            int y=to[i];du[y]--;
            dp[y]=(dp[y]+dp[x]*ksm(cd[x],mod-2))%mod;
            if(!du[y])q.push(y);
        }
    }
    //fo(i,1,n)cout<<sum[i]<<" "<<dp[i]<<endl;
    fo(i,n-r+1,n)printf("%lld ",(dp[i]+sum[i])%mod);
    return 0;
}
posted @ 2021-11-04 16:35  fengwu2005  阅读(71)  评论(0)    收藏  举报