首页 > 技术文章 > 北京集训DAY7

whistle13326 原文

 1 /*
 2      用到了容斥原理,加上1个数的个数,减去两两相交的个数,加上三三相交   的个数,减去四四相交的个数。。。。
 3 想出正解,结果蜜汁20.。。。。
 4 */
 5 #include<iostream>
 6 #include<algorithm>
 7 #include<cstdio>
 8 #include<cstring>
 9 #include<cmath>
10 #include<cstdlib>
11 using namespace std;
12 typedef long long ll;
13 typedef long double ld;
14 typedef pair<int,int> pr;
15 const double pi=acos(-1);
16 #define rep(i,a,n) for(int i=a;i<=n;i++)
17 #define per(i,n,a) for(int i=n;i>=a;i--)
18 #define Rep(i,u) for(int i=head[u];i;i=Next[i])
19 #define clr(a) memset(a,0,sizeof a)
20 #define pb push_back
21 #define mp make_pair
22 #define putk() putchar(' ')
23 ld eps=1e-9;
24 ll pp=1000000007;
25 ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
26 ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
27 ll gcd(ll a,ll b){return (!b)?a:gcd(b,a%b);}
28 ll read(){
29     ll ans=0;
30     char last=' ',ch=getchar();
31     while(ch<'0' || ch>'9')last=ch,ch=getchar();
32     while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
33     if(last=='-')ans=-ans;
34     return ans;
35 }
36 void put(ll a){
37     if(a<0)putchar('-'),a=-a;
38     int top=0,q[20];
39     while(a)q[++top]=a%10,a/=10;
40     top=max(top,1);
41     while(top--)putchar('0'+q[top+1]);
42 }
43 //head
44 ll ans=0;
45 int n,m,a[25];
46 ll Gcd(ll a,ll b){
47     if(!b)return a;
48     return gcd(b,a%b);
49 }
50 void dfs(int dep,ll t,int flag){
51     if(t>n)return;
52     if(dep==m+1){
53         ans+=n/t*flag;
54         return;
55     }
56     dfs(dep+1,t,flag);
57     dfs(dep+1,t/Gcd(t,a[dep])*a[dep],-flag);
58 }
59 int main(){
60     n=read();
61     m=read();
62     rep(i,1,m)a[i]=read();
63     dfs(1,1,1);
64     cout<<ans<<endl;
65     return 0;
66 }
代码

  1 /*
  2     51Nod 第k大的区间2
  3     对于60%数据:我们需要对程序进行优化,枚举左端点的时候,要固定右端  点。
  4 可以再n^3内算出。根据插入排序,我们可以找出中位数找出
  5 对于80%数据:一般求第k大,一般都是需要二分答案。我们二分中位数大于等于k有多少个,二分完中位数大于等于k个。
  6 比如说:
  7 A 1  2 3 4 5  k=3
  8 B -1 -1 1 1 1 
  9 因为1,2是小于零,根君b数组进行判断有多少个大于等于k个。我们二分答案,再暴力一下,可以拿到80%
 10 对于100%数据,我们要拿前缀和s[r]进行判断。我们要让s[r]-s[l-1]>0,我们要求逆序对,我们统计顺序对的个数,求逆序对是nlogn,总时间复杂度是nlognlogn
 11 */
 12 #include<iostream>
 13 #include<algorithm>
 14 #include<cstdio>
 15 #include<cstring>
 16 #include<cmath>
 17 #include<cstdlib>
 18 using namespace std;
 19 typedef long long ll;
 20 typedef long double ld;
 21 typedef pair<int,int> pr;
 22 const double pi=acos(-1);
 23 #define rep(i,a,n) for(int i=a;i<=n;i++)
 24 #define per(i,n,a) for(int i=n;i>=a;i--)
 25 #define Rep(i,u) for(int i=head[u];i;i=Next[i])
 26 #define clr(a) memset(a,0,sizeof a)
 27 #define pb push_back
 28 #define mp make_pair
 29 #define fi first
 30 #define sc second
 31 ld eps=1e-9;
 32 ll pp=1000000007;
 33 ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
 34 ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
 35 ll read(){
 36     ll ans=0;
 37     char last=' ',ch=getchar();
 38     while(ch<'0' || ch>'9')last=ch,ch=getchar();
 39     while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
 40     if(last=='-')ans=-ans;
 41     return ans;
 42 }
 43 //head
 44 #define N 110000
 45 int a[N],b[N],c[N],d[N],e[N],n,m;
 46 ll k;
 47 int lowbit(int x){
 48     return x&(-x);
 49 }
 50 int bin(int k){
 51     int l=1,r=m;
 52     while(l<r){
 53         int mid=(l+r)/2;
 54         if(k<=d[mid])r=mid;
 55         else l=mid+1;
 56     }
 57     return l;
 58 }
 59 void add(int x){
 60     for(;x<=m;x+=lowbit(x))e[x]++;
 61 }
 62 int find(int x){
 63     int ans=0;
 64     for(;x;x-=lowbit(x))ans+=e[x];
 65     return ans;
 66 }
 67 ll check(int k){
 68     c[0]=0;
 69     rep(i,1,n)c[i]=c[i-1]+(a[i]>=k);
 70     rep(i,0,n)c[i]=c[i]*2-i,d[i+1]=c[i];
 71     sort(d+1,d+n+2);
 72     d[0]=1;
 73     rep(i,2,n+1)
 74         if(d[i]!=d[d[0]])d[++d[0]]=d[i];
 75     m=d[0];
 76     ll ans=0;
 77     rep(i,0,n)c[i]=bin(c[i]);
 78     rep(i,0,m)e[i]=0;
 79     rep(i,0,n)
 80         if(i&1)add(c[i]);
 81         else ans+=find(c[i]-1);
 82     rep(i,0,m)e[i]=0;
 83     rep(i,0,n)
 84         if((i&1)==0)add(c[i]);
 85         else ans+=find(c[i]-1);
 86     return ans;
 87 }
 88 int main(){
 89     n=read();k=read();
 90     rep(i,1,n)a[i]=read(),b[i]=a[i];
 91     sort(b+1,b+n+1);
 92     b[0]=1;
 93     rep(i,2,n)
 94         if(b[i]!=b[b[0]])b[++b[0]]=b[i];
 95     int l=1,r=b[0];
 96     while(l<r){
 97         int mid=(l+r)/2+1;
 98         ll tt=check(b[mid]);
 99         if(tt==k){
100             cout<<b[mid]<<endl;
101             return 0;
102         }
103         if(check(b[mid])>k)l=mid;
104         else r=mid-1;
105     }
106     cout<<b[l]<<endl;
107     return 0;
108 }
代码

 1 /*
 2     这还是51Nod 上的一道题,忘了叫啥了
 3     对于60%数据,每一次排序只新增一个数字,我们可以进行插入排序,这样我们可以n^3做这道题。
 4 对于80%数据:首先我们来考虑一下,一个区间是5,k=4,那么会被统计4次,这个数字被统计了多少次,说明有多少个数字小于他。一个数比他小,则会对这个数字多贡献一下
 5 我们把t变一下,比如说还有t2,那么还有i2这一段比他小
 6 Sum=i+i2
 7 Sum*(n-j+1)*k。所以我们只需要求出比k小的下标有多少个。
 8 我们可以暴力做
 9 
10 对于100%数据:我们每一次找到比他小的下标进行维护,我们可以那树状数组,线段树甚至归并排序求出。我们先求出下标总和
11 比如:10 100 1000  数据
12       1   2   3   下标
13 这样我们可以那归并排序进行维护即可。
14 */
15 #include<iostream>
16 #include<algorithm>
17 #include<cstdio>
18 #include<cstring>
19 #include<cmath>
20 #include<cstdlib>
21 using namespace std;
22 typedef long long ll;
23 typedef long double ld;
24 typedef pair<int,int> pr;
25 const double pi=acos(-1);
26 #define rep(i,a,n) for(int i=a;i<=n;i++)
27 #define per(i,n,a) for(int i=n;i>=a;i--)
28 #define Rep(i,u) for(int i=head[u];i;i=Next[i])
29 #define clr(a) memset(a,0,sizeof a)
30 #define pb push_back
31 #define mp make_pair
32 #define fi first
33 #define sc second
34 ld eps=1e-9;
35 ll pp=1000000007;
36 ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
37 ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
38 ll read(){
39     ll ans=0;
40     char last=' ',ch=getchar();
41     while(ch<'0' || ch>'9')last=ch,ch=getchar();
42     while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
43     if(last=='-')ans=-ans;
44     return ans;
45 }
46 //head
47 #define N 1100000
48 pr a[N];
49 int c1[N],c2[N],n;
50 ll A,B,C;
51 int lowbit(int x){return x&(-x);}
52 void add(int *c,int x,int w){
53     c[0]+=w;
54     if(c[0]>=pp)c[0]-=pp;
55     for(;x<=n;x+=lowbit(x)){
56         c[x]=c[x]+w;
57         if(c[x]>=pp)c[x]-=pp;
58     }
59 }
60 int find(int *c,int x){
61     int ans=0;
62     for(;x;x-=lowbit(x)){
63         ans+=c[x];
64         if(ans>=pp)ans-=pp;
65     }
66     return ans;
67 }
68 int main(){
69     cin>>n>>a[1].fi>>A>>B>>C;
70     a[1].sc=1;
71     rep(i,2,n){
72         a[i].sc=i;
73         a[i].fi=(a[i-1].fi*A+B)%C;
74     }
75     sort(a+1,a+n+1);
76     ll ans=0;
77     rep(i,1,n){
78         int t1=find(c1,a[i].sc);
79         int t2=c2[0]-find(c2,a[i].sc-1);
80         t2=(t2+pp)%pp;
81         int t3=(1ll*t1*(n-a[i].sc+1)+1ll*t2*a[i].sc)%pp;
82         t3=(t3+1ll*a[i].sc*(n-a[i].sc+1))%pp;
83         ans=(ans+1ll*t3*a[i].fi)%pp;
84         add(c1,a[i].sc,a[i].sc);
85         add(c2,a[i].sc,n-a[i].sc+1);
86     }
87     cout<<ans<<endl;
88     return 0;
89 }
代码

推荐阅读