其实这场我爆零了,都是队友A的题,现在滚过来补题了。。。

可补题:A先欠着

B. super_log

这个题运用了扩展欧拉降幂

2019 南京网络赛 B、F、H_快速幂

于是我O(n)的去求每一层的底数和幂数??成功超时。

然后搜题解:

2019 南京网络赛 B、F、H_i++_02

waht???类似减了一下枝就可以了?当时队友告诉我用什么快速幂套快速幂????这种题可以快速幂套快速幂??

成功被队友带歪,怎么说呢,自己也菜,队友也菜,队友菜的同时还喜欢拿假的思路瞎搞,带歪我。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
map<int,int> euler;
ll a,b,mod;
int phi(int n)
{
    int now=n;
    int ret=n;
    if(euler.count(now)) return euler[now];
    for(int i=2;i<=sqrt(n);i++)
    {
        if(n%i==0)
        {
            ret=ret/i*(i-1);
            while(n%i==0)
                n/=i;
        }
    }
    if(n>1)
        ret=ret/n*(n-1);
    euler[now]=ret;
    return ret;
}
ll MOD(ll n,int mod)
{
    return n<mod?n:(n%mod+mod);//其实只跟公式的后两个有关
}
ll quick_mod(ll base,ll p,int mod)
{
    ll ret=1;
    do{
        if(p&1)
            ret=MOD(base*ret,mod);
        base=MOD(base*base,mod);
    }while(p>>=1);
    return ret;
}
ll solve(int l,int r,int mod)
{
    if(l==r||mod==1) return MOD(a,mod);//减枝了
    return quick_mod(a,solve(l+1,r,phi(mod)),mod);
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
    	scanf("%lld%lld%lld",&a,&b,&mod);
    	if(a==1||b==0){
    		printf("%d\n",1%mod);
    		continue;
		}
		if(b==1){
			printf("%d\n",a%mod);
			continue;
		}
        ll ans=solve(1,b,mod)%mod;
        printf("%lld\n",ans);
	}
}

F Greedy Sequence

线段树从小到大维护一下就可以了。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int mx[4*N],sz[N],a[N],vis[N];
int n,k;
void up(int id,int l,int r,int pos,int val)
{
    if(l==r){
        mx[id]=val;return;
    }
    int mid=l+r>>1;
    if(pos<=mid) up(id<<1,l,mid,pos,val);
    else up(id<<1|1,mid+1,r,pos,val);
    mx[id]=max(mx[id<<1],mx[id<<1|1]);
}
int qu(int id,int l,int r,int ql,int qr)
{
    if(ql<=l&&r<=qr) return mx[id];
    int mid=l+r>>1;
    int ans=0;
    if(ql<=mid) ans=qu(id<<1,l,mid,ql,qr);
    if(qr>mid) ans=max(ans,qu(id<<1|1,mid+1,r,ql,qr));
    return ans;
}
int main()
{
    int _;cin>>_;while(_--)
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=4*n;++i) mx[i]=0;
        for(int i=1;i<=n;++i) {
            scanf("%d",&a[i]);
            sz[i]=0;
            vis[a[i]]=i;
        }
        //sz[0]=1;
        for(int i=1;i<=n;++i)
        {
            int ql=max(vis[i]-k,1);
            int qr=min(vis[i]+k,n);
            int ans=qu(1,1,n,ql,qr);
            //printf("ans:%d\n",ans);
            sz[i]=sz[ans]+1;
            up(1,1,n,vis[i],i);
        }
        for(int i=1;i<=n;++i)
        {

            if(i==1)printf("%d",sz[i]);
            else printf(" %d",sz[i]);
        }
        puts("");
    }
}

H-Holy Grail

答案就是floyd的最短路径取负值

接着将新加入的边加进去再跑一次floyd,依次类推

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
using namespace std;
typedef long long ll;
const int N=1e3+10;
ll dis[N][N];
int n,m;
void floyd()
{
    for(int k=0;k<n;k++)
    for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)
    dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
int main()
{
    int _;cin>>_;while(_--)
    {
        scanf("%d%d",&n,&m);
        memset(dis,0x3f3f3f3f3f3f3f3f,sizeof(dis));
        //printf("m:%d\n",m);
        rep(i,1,m)
        {
            int u,v;ll w;scanf("%d%d%lld",&u,&v,&w);
            dis[u][v]=w;
        }
        rep(i,1,n) dis[i][i]=0;
        for(int i=1;i<=6;++i)
        {
            floyd();
            int u,v;scanf("%d%d",&u,&v);
            printf("%lld\n",-dis[v][u]);
            dis[u][v]=-dis[v][u];

        }
    }
}