Multi school sprint noip 11.04

Multi school sprint noip 11.04

Big score today!! I don't...

So when can I consider the situation completely!!

When can I drop the data of my program card!!

Factorial of T1 puzzle

This question can be cut if you do it casually. Really do it casually

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 subset

The rule I'm looking for doesn't seem easy to describe, so look at the code

In the examination room, I wrote one myself because I couldn't use the official \ (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 concrete powder

This question should be a routine, but I haven't seen it. Then I didn't think of it because my IQ was a little low

First of all, we know that if you put sand in a certain time, it will contribute to a certain inquiry

We need to guarantee two conditions:

The first is spatially, the modification must override the query

The second is in terms of time. The modification must be made before the inquiry

We find that the meaning of this question can be transformed into asking the earliest time when the height at the position of \ (x \) is greater than \ (y \)

After this conversion, it is easy to find that bisection can be used, but the following maintenance is required

Finding dichotomy requires interval additivity, but what we call space is interval non additivity

So we scan the space and use the segment tree to maintain the time

For each query, we add the height at the left end of the bedrock axis and subtract the height at the right end

For each query, we can also put it on the bedrock axis, which can be bisected directly on the line segment tree

The segment tree maintains a timeline

We scan this bedrock axis directly

If you need to add, add it at the corresponding time on the line segment tree and subtract it

The query is directly on the left half of the query time

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 drainage system

I was silly in the examination room. I didn't see that only one was broken. There was also \ (36pts \) for direct transfer

So we can maintain the expected change value of each position

Because only one edge is broken, we can push it according to the unchanged one first

At this time, the change value of each point is calculated

Push again and lower the change value

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 on Thu, 04 Nov 2021 14:46:11 -0400 by fishfin