• 小Z的袜子「国家集训队」


    题意

    给定一个数列以及若干询问,每次询问给定区间任意挑选两个数相等的概率。


    思路

    对于每一种颜色显然贡献为(cnt[c]*(cnt[c]-1)),由于我们一个个加入,所以说在加上现在贡献的同时需要减去之前的计算,即

    [+cnt[c]*(cnt[c]-1)-(cnt[c]-1)*(cnt[c]-2) ]

    化简得到(+cnt[c]*2-2)

    减去同理。

    注意需要特判区间长度为1的毒瘤情况。

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    namespace StandardIO {
    
    	template<typename T>inline void read (T &x) {
    		x=0;T f=1;char c=getchar();
    		for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
    		for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
    		x*=f;
    	}
    
    	template<typename T>inline void write (T x) {
    		if (x<0) putchar('-'),x*=-1;
    		if (x>=10) write(x/10);
    		putchar(x%10+'0');
    	}
    
    }
    
    using namespace StandardIO;
    
    namespace Project {
    	#define int long long
    	
    	const int N=50050;
    	
    	int n,m,block;
    	int a[N];
    	struct ask {
    		int l,r,id;
    	} q[N];
    	int res,cnt[N];
    	pair<int,int> ans[N];
    	
    	inline int gcd (int a,int b) {
    		return (b==0)?a:gcd(b,a%b);
    	}
    	inline bool cmp (const ask x,const ask y) {
    		return (x.l/block!=y.l/block)?(x.l/block<y.l/block):(((x.l/block)&1)?(x.r<y.r):(x.r>y.r));
    	}
    	inline void add (int x) {
    		++cnt[a[x]];
    		if (cnt[a[x]]>1) res+=2*cnt[a[x]]-2;
    	}
    	inline void del (int x) {
    		--cnt[a[x]];
    		if (cnt[a[x]]>0) res-=cnt[a[x]]*2;
    	}
    
    	inline void MAIN () {
    		read(n),read(m),block=sqrt(n);
    		for (register int i=1; i<=n; ++i) 
    			read(a[i]);
    		for (register int i=1; i<=m; ++i) {
    			read(q[i].l),read(q[i].r),q[i].id=i;
    		}
    		sort(q+1,q+m+1,cmp);
    		int l=1,r=0;
    		for (register int i=1; i<=m; ++i) {
    			if (q[i].l==q[i].r) {
    				ans[q[i].id].first=0,ans[q[i].id].second=1;
    				continue;
    			}
    			while (l>q[i].l) add(--l);
    			while (l<q[i].l) del(l++);
    			while (r<q[i].r) add(++r);
    			while (r>q[i].r) del(r--);
    			int len=(r-l+1)*(r-l),tmp=gcd(res,len);
    			ans[q[i].id].first=res/tmp,ans[q[i].id].second=len/tmp;
    		}
    		for (register int i=1; i<=m; ++i) {
    			write(ans[i].first),putchar('/'),write(ans[i].second),puts("");
    		}
    	}
    	
    	#undef int
    }
    
    int main () {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	Project::MAIN();
    }
    
    
  • 相关阅读:
    Android Studio中使用AAR包
    Unity Hub无法添加新模块解决办法
    WTM(基于Vue)项目发布记录
    企业微信自建应用开发
    企业微信接口上传临时素材
    cfw for ubuntu
    行锁,间隙锁,快照读,当前读的理解。
    spring容器之ApplicationContext
    select_poll_epoll
    百万级抽奖系统——redis的延时双删——数据库与缓存的数据一致性问题分析
  • 原文地址:https://www.cnblogs.com/ilverene/p/11746219.html
Copyright © 2020-2023  润新知