本文共 2341 字,大约阅读时间需要 7 分钟。
莫队算法
这道题的话我们很容易用数组来实现,做到O(1)的从[l,r]转移到[l,r+1]与[l+1,r]。
那么莫队算法怎么做呢?以下都是在转移为O(1)的基础下讨论的时间复杂度。另外由于n与m同阶,就统一写n。
# include # include # include # include # include # include # include # include # include # include # include using namespace std;# define lowbit(x) ((x)&(-x))# define pi 3.1415926535# define eps 1e-9# define MOD 1000000009# define INF 1000000000# define mem(a,b) memset(a,b,sizeof(a))# define FOR(i,a,n) for(int i=a; i<=n; ++i)# define FO(i,a,n) for(int i=a; i PII;typedef vector VI;# pragma comment(linker, "/STACK:1024000000,1024000000")typedef long long LL;int Scan() { int res=0, flag=0; char ch; if((ch=getchar())=='-') flag=1; else if(ch>='0'&&ch<='9') res=ch-'0'; while((ch=getchar())>='0'&&ch<='9') res=res*10+(ch-'0'); return flag?-res:res;}void Out(int a) { if(a<0) {putchar('-'); a=-a;} if(a>=10) Out(a/10); putchar(a%10+'0');}const int N=50005;//Code begin...struct Query{ int L, R, id;}node[N];LL gcd(LL a, LL b){ return b==0?a:gcd(b,a%b);}struct Ans{ LL a, b; void reduce(){LL d=gcd(a,b); a/=d; b/=d;}}ans[N];int a[N], num[N], n, m, unit;bool comp(Query a, Query b){ if (a.L/unit!=b.L/unit) return a.L/unit node[i].R) { temp-=(LL)num[a[R]]*num[a[R]]; --num[a[R]]; temp+=(LL)num[a[R]]*num[a[R]]; --R; } while (L node[i].L) { --L; temp-=(LL)num[a[L]]*num[a[L]]; ++num[a[L]]; temp+=(LL)num[a[L]]*num[a[L]]; } ans[node[i].id].a=temp-(R-L+1); ans[node[i].id].b=(LL)(R-L+1)*(R-L); ans[node[i].id].reduce(); }}int main (){ scanf("%d%d",&n,&m); FOR(i,1,n) scanf("%d",a+i); FO(i,0,m) scanf("%d%d",&node[i].L,&node[i].R), node[i].id=i; unit=(int)sqrt(n); sort(node,node+m,comp); work(); FO(i,0,m) printf("%lld/%lld\n",ans[i].a,ans[i].b); return 0;}
转载于:https://www.cnblogs.com/lishiyao/p/6639390.html