• NOI2018


    归程

    Luogu
    LOJ
    UOJ
    BZOJ
    不难发现一定是先开车走一段路直到下条边海拔不超过水位,然后下车沿最短路走到(1)号点。
    按海拔降序建出Kruskal重构树,对于一次询问,找到(v)的祖先中深度最低的海拔高于水位低的点(u),那么(u)的子树中的叶子节点就是(v)可以开车到的点。
    预处理每个点到(1)号点的最短路(dis),然后维护每个节点子树中的叶子节点最小(dis)即可。

    #include<bits/stdc++.h>
    #define M 400007
    #define N 200007
    using namespace std;
    namespace IO
    {
        char ibuf[(1<<21)+1],obuf[(1<<21)+1],st[15],*iS,*iT,*oS=obuf,*oT=obuf+(1<<21);
        char Get() { return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++); }
        void Flush() { fwrite(obuf,1,oS-obuf,stdout),oS=obuf; }
        void Put(char x) { *oS++=x; if(oS==oT) Flush(); }
        int read(){int x=0;char ch=Get();while(ch>57||ch<48)ch=Get();while(ch>=48&&ch<=57)x=x*10+(ch^48),ch=Get();return x;}
        void write(int x) {int top=0; if(!x) Put('0'); while(x) st[++top]=(x%10)+48,x/=10; while(top) Put(st[top--]); Put('
    '); }
    }
    using namespace IO;
    struct EDGE{int u,v,w;}Edge[M];
    int operator<(EDGE a,EDGE b){return a.w>b.w;}
    struct dot{int u,d;};
    int operator<(dot a,dot b){return a.d>b.d;}
    priority_queue<dot>q;
    int tot,head[N<<1],ver[M<<1],Next[M<<1],edge[M<<1],dis[N<<1],vis[N],dep[N<<1],val[N<<1],fa[N<<1],f[N<<1][20];
    void add(int u,int v,int w=0){ver[++tot]=v,Next[tot]=head[u],edge[tot]=w,head[u]=tot;}
    int Find(int x){return x==fa[x]? x:fa[x]=Find(fa[x]);}
    void dfs(int u,int Fa)
    {
        dep[u]=dep[Fa]+1,f[u][0]=Fa;
        for(int i=1;i<=19;++i) f[u][i]=f[f[u][i-1]][i-1];
        for(int i=head[u],v;i;i=Next[i]) dfs(v=ver[i],u),dis[u]=min(dis[u],dis[v]);
    }
    int query(int u,int p)
    {
        for(int i=19;~i;--i) if((dep[u]>1<<i)&&val[f[u][i]]>p) u=f[u][i];
        return dis[u];
    }
    int main()
    {
        int T,i,n,m,u,v,w,l,lastans,cnt,Q,K,S,num;
        for(T=read();T;--T)
        {
    	num=lastans=tot=0,n=read(),m=read(),memset(head,0,sizeof head),memset(f,0,sizeof f);
    	for(i=1;i<=m;++i) u=read(),v=read(),l=read(),w=read(),add(u,v,l),add(v,u,l),Edge[i]=EDGE{u,v,w};
        
    	memset(vis,0,sizeof vis),memset(dis,0x3f,sizeof dis),dis[1]=0,q.push(dot{1,0});
    	while(!q.empty())
    	{
    	    u=q.top().u,q.pop();
    	    if(vis[u]) continue;
    	    for(vis[u]=1,i=head[u];i;i=Next[i]) if(!vis[v=ver[i]]&&dis[v]>dis[u]+edge[i]) dis[v]=dis[u]+edge[i],q.push(dot{v,dis[v]});
    	}
        
    	memset(head,0,sizeof head),tot=0,cnt=n,sort(Edge+1,Edge+m+1);
    	for(i=1;i<=n<<1;++i) fa[i]=i;
    	for(i=1;i<=m;++i) if((u=Find(Edge[i].u))^(v=Find(Edge[i].v))){val[++cnt]=Edge[i].w,fa[u]=fa[v]=cnt,add(cnt,u),add(cnt,v),++num;if(num==n-1)break;};
    	dfs(cnt,0);
    
    	Q=read(),K=read(),S=read();
    	while(Q--) u=(K*lastans+read()-1)%n+1,v=(K*lastans+read())%(S+1),write(lastans=query(u,v));
        }
        return Flush(),0;
    }
    

    屠龙勇士

    Luogu
    LOJ
    UOJ
    BZOJ
    Ex-CRT模板题。

    #include<set>
    #include<cctype>
    #include<cstdio>
    #include<algorithm>
    using i64=long long;
    const int N=100007;
    i64 a[N],b[N],p[N];
    i64 read(){i64 x=0;char c=getchar();while(isspace(c))c=getchar();while(isdigit(c))(x*=10)+=c&15,c=getchar();return x;}
    i64 gcd(i64 n,i64 m){return !m? n:gcd(m,n%m);}
    void exgcd(i64 a,i64 b,i64&x,i64&y){!b? (x=1,y=0):(exgcd(b,a%b,y,x),y-=a/b*x);}
    i64 mul(i64 a,i64 b,i64 p){return (__int128)a*b%p;}
    void solve()
    {
        int n=read(),m=read(),flg=!n||!!m;std::multiset<i64>s;
        for(int i=1;i<=n;++i) a[i]=read();
        for(int i=1;i<=n;++i) p[i]=read();
        for(int i=1;i<=n;++i) b[i]=read();
        for(int i=1;i<=m;++i) s.insert(read());
        i64 lim=0,A=0,B=1;
        for(int i=1;i<=n&&flg;++i)
        {
    	auto it=s.upper_bound(a[i]);
    	if(it!=s.begin()) --it;
    	i64 q=*it;
    	s.erase(it),s.insert(b[i]),lim=std::max(lim,(a[i]+q-1)/q),a[i]%=p[i],q%=p[i];
    	i64 g=gcd(B*q,p[i]),x,y;
    	if((a[i]-q*A)%g) {flg=0;break;}
    	exgcd(B*q,p[i],x,y),x=mul(x,(a[i]-q*A)/g,p[i]),y=p[i]/g*B,A=(A+mul(B,x,y))%y,B=y;
        }
        printf("%lld
    ",flg? (lim-A+B-1)/B*B+A:-1);
    }
    int main()
    {
        for(int t=read();t;--t) solve();
    }
    
  • 相关阅读:
    centos6 安装 directAdmin
    rpm源码安装mysql
    linux添加自启服务(程序)
    linux配置ip的方法
    开发规范
    Video Processing and Communications:(视频处理和通信)
    低清图像变成高清图像 原理
    CentOS和Ubuntu哪个好?
    遥感图像处理与一般的图像处理的区别
    GAE、SAE与BAE的对比分析(百度云)
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/13016554.html
Copyright © 2020-2023  润新知