Liers 树状数组+中国剩余定理

Liers

Time Limit: 14000/7000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others)

SubmitStatus

Problem Description

有N个人,其中有若干个人一起参加了舞会,现在想知道哪些人有可能参加了舞会,你问了N个人,第i个人说参加舞会的人数在[Li,Ri]区间的一个数,问有多少种合法的舞会人数方案?所谓合法方案是指,参加舞会的所有人说的都是真话,即参加舞会的人中,舞会总人数符合所有参加舞会的人的话语(不一定符合没有参加舞会的人的话语),即在其区间中。假设参加了舞会的人说的都是真话。

Input

多组数据,每组数据:

第一行,N(1 <= N <= 10^6),总人数

从2到N + 1行,每行两个正整数,L,R,表示第i个人说的,舞会总人数为[L,R]中的一个数  -2^31 <= L,R  <= 2^31 - 1(int)

Output

每组数据输出一行,总合法数 % 20140717

Sample Input

3
1 1
1 1
1 1
3
0 2
0 2
0 2

Sample Output

3
6

Hint

第二个样例说明,舞会可能只有一个人参加,这样由3种情况,1或者2或者3,也可能2个人参加,(1,2)或(1,3)或(2,3),注意,一个合理的舞会至少需要有一个人

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <math.h>
  4 #include <string.h>
  5 #include <algorithm>
  6 using namespace std;
  7 #define mod 20140717LL
  8 #define ll long long
  9 typedef struct people
 10 {
 11     int l,r;
 12 } people;
 13 people p[1000001];
 14 int b[1000001],n;
 15 short int a1[46][46]= {0},a2[110][110]= {0},a3[4599][4599]= {0};
 16 void init()
 17 {
 18     int i,j;
 19     a1[0][0]=a2[0][0]=a3[0][0]=1;
 20     for(i=1; i<4599; i++)
 21     {
 22         a3[i][i]=a3[i][0]=1;
 23         for(j=1; j<i; j++)
 24             a3[i][j]=a3[i-1][j-1]+a3[i-1][j],a3[i][j]%=4591;
 25     }
 26     for(i=1; i<110; i++)
 27     {
 28         a2[i][i]=a2[i][0]=1;
 29         for(j=1; j<i; j++)
 30             a2[i][j]=a2[i-1][j-1]+a2[i-1][j],a2[i][j]%=107;
 31     }
 32     for(i=1; i<46; i++)
 33     {
 34         a1[i][i]=a1[i][0]=1;
 35         for(j=1; j<i; j++)
 36             a1[i][j]=a1[i-1][j-1]+a1[i-1][j],a1[i][j]%=41;
 37     }
 38 }
 39 int lowbit(int x)
 40 {
 41     return x&(-x);
 42 }
 43 void update(int x,int z)
 44 {
 45     while(x>0)
 46     {
 47         b[x]+=z;
 48         x-=lowbit(x);
 49     }
 50 }
 51 int query(int x)
 52 {
 53     int sum=0;
 54     while(x<=n)
 55     {
 56         sum+=b[x];
 57         x+=lowbit(x);
 58     }
 59     return sum;
 60 }
 61 int fun1(int m,int x,int y)
 62 {
 63     int ans=1;
 64     while(x)
 65     {
 66         if(y==41)
 67             ans*=a1[m%y][x%y];
 68         else if(y==107)
 69             ans*=a2[m%y][x%y];
 70         else ans*=a3[m%y][x%y];
 71         m/=y,x/=y;
 72     }
 73     return ans;
 74 }
 75 int fun(int m,int x)
 76 {
 77     ll m1,m2,m3;
 78     m1=fun1(m,x,41);
 79     m2=fun1(m,x,107);
 80     m3=fun1(m,x,4591);
 81     int ans=((m1*8842266LL)%mod+(m2*1129386LL)%mod+(m3*10169066LL)%mod)%mod;
 82     return ans;
 83 }
 84 int main()
 85 {
 86     // freopen("in.txt","r",stdin);
 87     init();
 88     int i,j,ans,m;
 89     while(scanf("%d",&n)!=EOF)
 90     {
 91         for(i=0; i<n; i++)
 92         {
 93             scanf("%d%d",&p[i].l,&p[i].r);
 94             if(p[i].l<=0)p[i].l=1;
 95             if(p[i].l>n)p[i].r=n;
 96             if(p[i].r<=0)p[i].r=1;
 97             if(p[i].r>n)p[i].r=n;
 98         }
 99         memset(b,0,sizeof(b));
100         for(i=0; i<n; i++)
101         {
102             update(p[i].r,1);
103             update(p[i].l-1,-1);
104         }
105         ans=0;
106         for(i=1; i<=n; i++)
107         {
108             m=query(i);
109             if(m>=i)
110                 ans+=fun(m,i),ans%=mod;
111         }
112         printf("%d\n",ans%mod);
113     }
114
115 }

Liers 树状数组+中国剩余定理

时间: 2024-10-10 16:08:47

Liers 树状数组+中国剩余定理的相关文章

USACO5.3 IDDFS_强连通_二维树状数组_斐蜀定理_矩形切割

启发式搜索 启发式搜索的主要思想是通过评价一个状态有"多好"来改进对于解的搜索. 方法#1:启发式剪枝 估价函数最简单最普通的用法是进行剪枝.假设有一个求最小代价的一个搜索,使用一个可行的估价函数.如果搜到当前状态时代价为A,这个状态的估价函数是B,那么从这个状态开始搜所能得到的最小代价是A+B.如果当前最优解是C满足C 方法#2:最佳优先搜索 最佳搜索可以看成贪心的深度优先搜索. 与一般搜索随意扩展后继节点不同,最优优先搜索按照估价函数所给的他们的"好坏"的顺序扩

2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ&#39;s Salesman 【离散化+树状数组维护区间最大值】

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 919    Accepted Submission(s): 290 Problem Description YJJ is a salesman who h

hdu 4456 Crowd(二维树状数组)

题目链接:hdu 4456 Crowd 题目大意:给定N,然后M次操作 1 x y z:在x,y的位置加z 2 x y z:询问与x,y曼哈顿距离小于z的点值和. 解题思路:将矩阵旋转45度,然后询问就等于是询问一个矩形,可以用容斥定理搞,维护用二维树状数组,但是空间开 不下,直接用离散化,将有用到的点处理出来. #include <cstdio> #include <cstring> #include <algorithm> using namespace std;

cf 830B - Cards Sorting 树状数组

B. Cards Sorting time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Vasily has a deck of cards consisting of n cards. There is an integer on each of the cards, this integer is between 1 and 10

uva 12356 Army Buddies 树状数组解法 树状数组求加和恰为k的最小项号 难度:1

Nlogonia is fighting a ruthless war against the neighboring country of Cubiconia. The Chief General of Nlogonia's Army decided to attack the enemy with a linear formation of soldiers, that would advance together until conquering the neighboring count

树状数组区间更新

在今天的文章开始之前,给大家提一个建议,由于线段树和树状数组这两个结构的分析有很多联系,因此,建议没有看前几篇文章的朋友一定需要了解一下前面的内容.链接如下: 线段树+RMQ问题第二弹 线段树第二弹(区间更新) 树状数组(Binary Indexed Tree,BIT) 上篇文章我们讨论了树状数组的基本结构以及它最擅长的两个功能:单点更新和区间求和,今天,我们来接着上一篇文章的内容继续深入研究.上篇文章我们是将树状数组和线段树进行对比讲解的,既然线段树的章节我们介绍了区间求和.区间最值.单点更新

POJ 2828——Buy Tickets(树状数组,线段树——逆序遍历)

Buy Tickets Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 13496   Accepted: 6726 Description Railway tickets were difficult to buy around the Lunar New Year in China, so we must get up early and join a long queue- The Lunar New Year wa

代码与算法集锦-归并排序+树状数组+快排+深度优先搜索+01背包(动态规划)

归并排序 求逆序数 归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的一个非常典型的应用. 首先考虑下如何将将二个有序数列合并.这个非常简单,只要从比较二个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数.然后再进行比较,如果有数列为空,那直接将另一个数列的数据依次取出即可. //将有序数组a[]和b[]合并到c[]中 void MemeryArray(int a[], int n, int b[], int m, int c

poj 2886 Who Gets the Most Candies? (树状数组+二分+反素数)

Who Gets the Most Candies? Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 11597   Accepted: 3616 Case Time Limit: 2000MS Description N children are sitting in a circle to play a game. The children are numbered from 1 to N in clockwise