• 「PKUSC2018」星际穿越&&「SCOI2015」国旗计划


    「PKUSC2018」星际穿越
    咕了很久的一道题
    (L_i=minlimits_{j=i}^nl_j)
    发现从x开始走一步可以到达的最小的点为(l_x) 最大的是满足(l_j le x)最靠右的(j)
    而第二次能到达的最靠左的点(L_{l_x}) 因为第一步到不了的右边的点的(l)一定不产生贡献
    记第(a)次能到达的最靠左的点为(b)(a+1)次可以到达的最靠左的点为(L_b)
    第二步及以后可以当作每次跳(L_i) 构成了树形结构 可以用主席树或者倍增之类的东西维护(对我来说倍增不好想不好写 太弱了)
    第一步只会有两种走法
    如果(yin[l_x,x-1]) 可以一步走到
    否则 跳到(jin[l_x,n])(l_j)最小的j 然后到达(L_{l_x})
    特殊判一下即可
    做了好长一段时间……

    #include<bits/stdc++.h>
    using namespace std;
    #define fp(i,l,r) for(register int (i)=(l);(i)<=(r);++(i))
    #define fd(i,l,r) for(register int (i)=(l);(i)>=(r);--(i))
    #define fe(i,u) for(register int (i)=front[(u)];(i);(i)=e[(i)].next)
    #define mem(a) memset((a),0,sizeof (a))
    #define O(x) cerr<<#x<<':'<<x<<endl
    #define int long long
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    void wr(int x){
        if(x<0)x=-x,putchar('-');
        if(x>=10)wr(x/10);
        putchar('0'+x%10);
    }
    const int MAXN=3e5+10;
    int gcd(int a,int b){return b?gcd(b,a%b):a;}
    int l[MAXN],L[MAXN],sum[MAXN*30],n;
    signed ls[MAXN*30],rs[MAXN*30],tag[MAXN*30],cnt,rt[MAXN];
    void mdy(signed &o,signed pre,int l,int r,int ql,int qr){
    	o=++cnt;tag[o]=tag[pre];sum[o]=sum[pre]+(qr-ql+1);ls[o]=ls[pre];rs[o]=rs[pre];
    	if(l==ql&&r==qr){++tag[o];return;}
    	int mid=l+r>>1;
    	if(qr<=mid)mdy(ls[o],ls[pre],l,mid,ql,qr);
    	else if(ql>mid)mdy(rs[o],rs[pre],mid+1,r,ql,qr);
    	else mdy(ls[o],ls[pre],l,mid,ql,mid),mdy(rs[o],rs[pre],mid+1,r,mid+1,qr);
    }
    int ask(signed o,int l,int r,int ql,int qr){
    	if(!o)return 0;
    	if(l==ql&&r==qr)return sum[o];
    	int mid=l+r>>1,res=(qr-ql+1)*tag[o];
    	if(qr<=mid)return res+ask(ls[o],l,mid,ql,qr);
    	else if(ql>mid)return res+ask(rs[o],mid+1,r,ql,qr);
    	else return res+ask(ls[o],l,mid,ql,mid)+ask(rs[o],mid+1,r,mid+1,qr);
    }
    main(){
    	n=read();
    	fp(i,2,n)l[i]=read();
    	L[n]=l[n];fd(i,n-1,2)L[i]=min(L[i+1],l[i]);
    	fp(i,2,n)mdy(rt[i],rt[L[i]],1,n,1,i-1);
    	int Q=read();
    	while(Q--){
    		int ql=read(),qr=read(),x=read();int t=min(qr,l[x]-1);
    		int t1=qr-ql+1,t2=t1+(ql<=t?ask(rt[l[x]],1,n,ql,t):0);
    		int g=gcd(t1,t2);
    		printf("%lld/%lld
    ",t2/g,t1/g);
    	}
    	return 0;
    }
    

    「SCOI2015」国旗计划
    破环为链
    (dp_{i,j})表示从(i)开始走(2^j)
    每次找的时候从其实位置走上m

  • 相关阅读:
    TCP带外数据
    ASP.Net Core 返回的json数据,自定义日期格式
    C# 简单的区块链实现
    PowerShell自动部署ASP.NET Core程序到 IIS
    ASP.NET Core依赖注入多个服务实现类
    EF Core 2.0 执行原始查询如何防止SQL注入
    C#7 进入快速迭代道路
    QuartzNet 任务管理系统
    WebApi如何传递参数
    C# 快速高效率复制对象另一种方式 表达式树
  • 原文地址:https://www.cnblogs.com/misaka10047/p/13186190.html
Copyright © 2020-2023  润新知