NPY and girls

NPY and girls

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5145

莫队算法

注意到没有修改区间的操作,使用莫队算法:将整个区间分成若干个块,将询问区间按块优先升序排序,同块内按区间右界升序排序,添加一个元素,满足条件的值sum就变为sum=(sum*times[a[r]]/(r-l+1));减少一个值同理。从第一个区间一直推到最后一个区间即可。(之前TLE一直以为是区间大小的问题,现在发现是这句话while(x<0)x+=M,不过因为这题M比较大,改改区间居然被我水过去了...)

代码如下:

  1 #include<cstdio>
  2 #include<cmath>
  3 #include<algorithm>
  4 #include<cstring>
  5 #define N 30005
  6 #define M 1000000007
  7 #define LL long long
  8 #define B 250/**((int)sqrt((double)n)) sqrt(n) will be TLE**/
  9 #define mst(x) memset(x,0,sizeof(x))
 10 using namespace std;
 11 LL times[N];
 12 LL T,n,m,x,y;
 13 LL a[N];
 14 struct nod{
 15     LL l,r,no,value;
 16 }q[N];
 17 LL exGCD(LL a,LL b){
 18     if(b==0){
 19         x=1;
 20         y=0;
 21         return a;
 22     }
 23     LL r=exGCD(b,a%b);
 24     LL tmp=x;
 25     x=y;
 26     y=tmp-(a/b)*y;
 27     return r;
 28 }
 29 bool cmp_by_range(nod x,nod y){
 30     if(x.l/B==y.l/B){
 31         return x.r<y.r;
 32     }else return (x.l/B<y.l/B);
 33 }
 34 bool cmp_by_no(nod x,nod y){
 35     return x.no<y.no;
 36 }
 37 void init(){
 38     mst(times);
 39     scanf("%I64d%I64d",&n,&m);
 40     for(LL i=0;i<n;++i)
 41         scanf("%I64d",&a[i]);
 42     for(LL i=0;i<m;++i){
 43         LL l,r;
 44         scanf("%I64d%I64d",&l,&r);
 45         l--,r--;
 46         q[i].l=l;
 47         q[i].r=r;
 48         q[i].no=i;
 49         q[i].value=0;
 50     }
 51     sort(q,q+m,cmp_by_range);
 52 }
 53 void solve(){
 54     LL l=q[0].l,r=q[0].r,sum=1;
 55     times[a[l]]++;
 56     for(LL i=l+1;i<=r;++i){
 57         times[a[i]]++;
 58         exGCD(times[a[i]],M);
 59         while(x<0)x+=M;
 60         sum=((sum*(i-l+1))%M*x)%M;
 61     }
 62     q[0].value=sum;
 63     for(LL i=1;i<m;++i){
 64         //l=q[i-1].l,r=q[i-1].r;
 65         while(r<q[i].r){
 66             r++;
 67             times[a[r]]++;
 68             exGCD(times[a[r]],M);
 69             while(x<0)x+=M;
 70             sum=((sum*(r-l+1))%M*x)%M;
 71         }
 72         while(r>q[i].r){
 73             exGCD((r-l+1),M);
 74             while(x<0)x+=M;
 75             sum=((sum*times[a[r]])%M*x)%M;
 76             times[a[r]]--;
 77             r--;
 78         }
 79         while(l<q[i].l){
 80             exGCD((r-l+1),M);
 81             while(x<0)x+=M;
 82             sum=((sum*times[a[l]])%M*x)%M;
 83             times[a[l]]--;
 84             l++;
 85         }
 86         while(l>q[i].l){
 87             l--;
 88             times[a[l]]++;
 89             exGCD(times[a[l]],M);
 90             while(x<0)x+=M;
 91             sum=((sum*(r-l+1)%M)*x)%M;
 92         }
 93         q[i].value=sum;
 94     }
 95 }
 96 int main(void){
 97     scanf("%I64d",&T);
 98     while(T--){
 99         init();
100         solve();
101         sort(q,q+m,cmp_by_no);
102         for(LL i=0;i<m;++i)
103             printf("%I64d\n",q[i].value);
104     }
105 }
时间: 2024-11-25 10:07:07

NPY and girls的相关文章

hdu NPY and girls 莫队+逆元

NPY and girls Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description NPY's girlfriend blew him out!His honey doesn't love him any more!However, he has so many girlfriend candidates.Because there are to

【HDU 5145】 NPY and girls(组合+莫队)

pid=5145">[HDU 5145] NPY and girls(组合+莫队) NPY and girls Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 593    Accepted Submission(s): 179 Problem Description NPY's girlfriend blew him out!H

hdu 5145 NPY and girls 莫队

题意: 给你1-n属于的班级 给你一个[l,r]区间 问你如果要访问这个区间内所有的女生 有多少种走不同教室的方法 思路: 和小z差不多 只不过这个维护的是阶乘 找出来公式之后莫队直接离线处理 莫队更多的是离线排序优化的思想 把所有查询排序处理 然后逐个处理 可以应用到很多方面 1 #include<bits/stdc++.h> 2 #define cl(a,b) memset(a,b,sizeof(a)) 3 #define debug cerr<<#a<<"

HDU 5145 NPY and girls(莫队算法+乘法逆元)

[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5145 [题目大意] 给出一个数列,每次求一个区间数字的非重排列数量.答案对1e9+7取模. [题解] 我们发现每次往里加入一个新的数字或者减去一个新的数字,前后的排列数目是可以通过乘除转移的,所以自然想到用莫队算法处理.因为答案要求取模,所以在用除法的时候要计算逆元. [代码] #include <cstdio> #include <algorithm> #include <

HDU 5145 NPY and girls (莫队分块离线)

题目地址:HDU 5145 莫队真的好神奇..这样的复杂度居然只有n*sqrt(n)... 裸的莫队分块,先离线,然后按左端点分块,按块数作为第一关键字排序,然后按r值作为第二关键字进行排序.都是从小到大,可以证明这样的复杂度只有n*sqrt(n).然后进行块之间的转移. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <

HDU 5145 NPY and girls 莫队算法

对于这类区间查询的问题,如果可以用O(1)的复杂度推到一个曼哈顿距离为1的另外区间的话,就可以直接用莫队算法搞. 从网上搜到的有两种搞法.第一种是先建立曼哈顿距离最小生成树,然后直接dfs遍历整棵树来求解的. 还有一种是先分块,然后把查询按照块的编号为第一关键字,右边界为第二关键字排序,排序直接直接暴力转移. 这样做的复杂度是n * sqrt(n),后面那个sqrt(n)取决于是怎么分块的. 仔细想想感觉这样子搞复杂度差不多就是这样,因为在同一个块中的复杂度怎么搞都是sqrt(n)级别的,就算是

Hdu5145NPY and girls莫队算法

Problem Description NPY's girlfriend blew him out!His honey doesn't love him any more!However, he has so many girlfriend candidates.Because there are too many girls and for the convenience of management, NPY numbered the girls from 1 to n.These girls

Girls&#39; research(manacher)

Girls' research Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 1160    Accepted Submission(s): 448 Problem Description One day, sailormoon girls are so delighted that they intend to research a

Girls and Boys(匈牙利)

Girls and Boys Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 9245    Accepted Submission(s): 4240 Problem Description the second year of the university somebody started a study on the romant