• Atcoder Grand Contest 023


    023D Go Home

    题目描述

    点此看题

    解法

    直接判断当前状态的决策是困难的,我们不妨逆推整个过程。考虑最后电车一定是再 \(1/n\) 停止的,那么我们大胆猜测,如果 \(p_1\geq p_n\),那么电车会先到 \(1\) 处,如果 \(p_1<p_n\),那么电车会先到 \(n\) 处。下面给出 \(p_1\geq p_n\) 会先到 \(1\) 处的证明(另一部分可以类似地证明):

    • \(n=2\),显然成立。
    • \(n>2\) 并且 \(s>x_{n-1}\),则除了 \(n\) 都会投票往左走,结论成立。
    • \(n>2\) 并且 \(s\leq x_{n-1}\),则如果列车到达 \(1\) 之前没有到达过 \(n-1\),则结论成立;否则可以化归到第二种情况。

    那么考虑 \(n\) 处到达的时间一定是 \(1\) 处到达的时间加上 \(x[n]-x[1]\),并且 \(n\) 就是最后到达的节点。那么等效子问题就特别明显了,我们让 \(p_1\leftarrow p_1+p_n\),然后把 \(n\) 删去,递归下去即可。递归的边界是不满足 \(x[l]<s<x[r]\),时间复杂度 \(O(n)\)

    #include <cstdio>
    #define int long long
    const int M = 100005;
    int read()
    {
    	int x=0,f=1;char c;
    	while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
    	while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
    	return x*f;
    }
    int n,s,x[M],p[M];
    int calc(int l,int r,int f)
    {
    	if(s<=x[l]) return x[r]-s;
    	if(s>=x[r]) return s-x[l];
    	if(p[l]>=p[r])
    	{
    		p[l]+=p[r];
    		return (f==r)*(x[r]-x[l])+calc(l,r-1,l);
    	}
    	p[r]+=p[l];
    	return (f==l)*(x[r]-x[l])+calc(l+1,r,r);
    }
    signed main()
    {
    	n=read();s=read();
    	for(int i=1;i<=n;i++)
    		x[i]=read(),p[i]=read();
    	printf("%lld\n",calc(1,n,p[1]<p[n]?1:n));
    }
    

    023E Inversions

    题目描述

    点此看题

    解法

    一看就只能算贡献,我们先考虑如何计算合法的排列数,首先把 \(a_i\) 排好序,设 \(p_i\) 表示排序后第 \(i\) 个元素在原序列上的位置,我们按照 \(a_i\) 的顺序填数,那么可供选择的方案是 \(a_i-i+1\)

    \[t=\prod_{i=1}^{n}(a_i-i+1) \]

    开始算贡献吧,考虑排序后序列上的两个位置 \(i<j\),我们对 \(p_i,p_j\) 的关系进行讨论。首先考虑 \(p_i<p_j\) 的情况,那么有贡献就需要 \(i\) 位置上填的数更大,考虑在总方案上略微修改,首先 \(i\) 的方案是 \(a_i-i+1\),根据等差数列选择 \(i,j\) 的方案是 \(\frac{(a_i-i+1)(a_i-i)}{2}\),注意 \(k\in(i,j)\) 的选择变少了 \(1\),综合考虑之后可以写出式子:

    \[\frac{t(a_i-i)}{2(a_j-j+1)}\prod_{k\in(i,j)} \frac{a_i-i}{a_i-i+1} \]

    对于 \(p_i>p_j\) 的情况,用总情况数去减就行了。

    现在很容易 \(O(n^2)\) 计算,优化考虑把连乘拆分成前缀积和前缀积逆元,我们枚举扫描 \(j\),用树状数组就可以轻易维护 \(p_i\)\(p_j\) 的关系。注意可能遇到没有逆元的情况,这时候前缀 \([1,i]\) 是没有 \(p_i<p_j\) 的方案的,可以直接清空树状数组,时间复杂度 \(O(n\log n)\)

    #include <cstdio>
    #include <vector>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int M = 200005;
    const int MOD = 1e9+7;
    #define int long long
    int read()
    {
    	int x=0,f=1;char c;
    	while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
    	while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
    	return x*f;
    }
    int n,t,ans,a[M],p[M],s[M],is[M],inv[M];
    pair<int,int> d[M];
    struct fenwick
    {
    	int tp,b[M],s[M];
    	void add(int x,int y)
    	{
    		s[++tp]=x;
    		for(int i=x;i<=n;i+=i&(-i))
    			b[i]=(b[i]+y)%MOD;
    	}
    	int ask(int x)
    	{
    		int r=0;
    		for(int i=x;i>=1;i-=i&(-i))
    			r=(r+b[i])%MOD;
    		return r;
    	}
    	void clear()
    	{
    		for(int o=1;o<=tp;o++)
    			for(int i=s[o];i<=n;i+=i&(-i))
    				b[i]=0;
    		tp=0;
    	}
    }f,g;
    signed main()
    {
    	n=read();inv[0]=inv[1]=1;
    	for(int i=2;i<=n;i++)
    		inv[i]=inv[MOD%i]*(MOD-MOD/i)%MOD;
    	for(int i=1;i<=n;i++)
    		a[i]=read(),d[i]={a[i],i};
    	sort(d+1,d+1+n);t=1;
    	for(int i=1;i<=n;i++)
    	{
    		int w=lower_bound(d+1,d+1+n,
    			make_pair(a[i],i))-d;
    		p[w]=i;t=t*max(0ll,a[i]-w+1)%MOD;
    	}
    	if(!t) {puts("0");return 0;}
    	for(int i=1;i<=n;i++)
    	{
    		if(!s[i-1])
    		{
    			s[i-1]=is[i-1]=1;
    			g.clear();
    		}
    		int x=a[p[i]];
    		s[i]=s[i-1]*(x-i)%MOD*inv[x-i+1]%MOD;
    		is[i]=is[i-1]*inv[x-i]%MOD*(x-i+1)%MOD;
    		int d=s[i-1]*inv[x-i+1]%MOD;
    		ans=(ans+i-1-f.ask(p[i]))%MOD;
    		ans=(ans-(g.ask(n)-2*g.ask(p[i]))*d)%MOD;
    		ans=(ans+MOD)%MOD;
    		g.add(p[i],(x-i)*inv[2]%MOD*is[i]%MOD);
    		f.add(p[i],1);
    	}
    	ans=ans*t%MOD;
    	printf("%lld\n",ans);
    }
    
  • 相关阅读:
    C# Path 目录
    Maxscript 窗体与结构体this的传递
    python---文件操作
    python---数据类型---集合
    python---购物车---更新
    python---三级菜单
    python---数据类型---字典
    python---数据类型---字符串
    python---购物车
    python---数据类型---列表
  • 原文地址:https://www.cnblogs.com/C202044zxy/p/16015348.html
Copyright © 2020-2023  润新知