多校终于结束了, 开始从后往前整理
4390 Number Sequence
容斥原理,
比赛的时候把10^25理解成2^25以为不会超long long, wa了好几次,最后队友提醒才看到
#include <cstdio> #include <cstring> #include <iostream> #include <queue> #include <cstdlib> #include <cmath> #include <stack> #include <map> #include <vector> #include <string> #include <algorithm> const double pi=cos(-1.); const double eps=10e-6; const double eps1=10e-9; const int inf=0x7fffffff; ///const int inf=0x3f3f3f3f; const long long infl=1ll<<62; ///******macro defination******/// #define cas(a) int a; scanf("%d", &a); while (a--) #define cas1(x, a) int a; scanf("%d", &a); for (int x=1; x<=a; ++x) #define int(a) int a; scanf("%d", &a) #define char(a) char a; scanf("%c", &a) #define strr(a, x) char a[x]; scanf("%s", &a) #define clean(a, x) memset (a, x, sizeof(a)); #define copy(a, b) memcpy(a, b, sizeof(a)); #define up(x,a) for(int x=0; x<a; ++x) #define down(x,a) for(int x=a-1; x>=0; --x) #define up1(x,a) for (int x=1; x<=a; ++x) #define debug(a) printf("here is %d!!!\n", a); ///*** mathmatics ***/// #define sqr(x) (x)*(x) #define abs(x) (x)>0?(x):(-(x)) #define zero(x) (x)<eps && (x)>eps #define lowbit(x) ((x)&(-(x))) ///*** for STL ***/// #define fst first #define scd second #define pb push_back #define mp makepair #define lb lower_bound #define ub upper_bound ///****** by Geners ******/// typedef long long ll; typedef unsigned int UI; using namespace std; const int mod=1000000007; const int maxn=200; #define vex edge[p].v //int w[maxn]; //struct Edge{int v, next;}edge[2*maxn]; //int head[maxn], cnt; //void addedge(int u, int v){ //edge[cnt].v=v; edge[cnt].next=head[u]; head[u]=cnt++; //} ///*** graphic theory***/// //ll C[2*maxn]; //int N; //int Query(int x){ // for (int res=0; ; res+=C[x], x-=lowbit(x))if(x==0)return res; //} //void Update(int x, int v){ // for (;x<=N; x+=lowbit(x))C[x]+=v; //} //void IUpdate(int s, int t, int v){ // Update(t+1, -v); Update(s, v); //} ///*** Binary Indexed Tree ***/// const int N=10000005; /// isprime and prime are both needed bool isprime[N>>1]={0}; /// N is the upper limit of primer int primes[700000]; /// maxn is more than prime[0] int init_prime1() { isprime[0]=1;/// 1 is not a primer primes[primes[0]=1]=2; /// 2 handmake int lim=N>>1; for(int i=1; i<lim; ++i)/// i<=lim st. 100000001 is a primer ,however that is not the case. { int j =i<<1|1; if(!isprime[i])primes[++primes[0]]=j; for (int k=2; k<=primes[0] && primes[k]*j<=N; ++k) { isprime[primes[k]*j>>1]=1; if(j%primes[k]==0)break; } } return primes[0]; } ll com[maxn][maxn]; void init() { init_prime1(); // debug(primes[0]); // for (int i=1; i<primes[0]; ++i)printf("%d\t", primes[i]); clean(com, 0); com[0][0]=1; com[1][0]=1; com[1][1]=1; for (int i=2; i<maxn; ++i) { com[i][0]=1; for (int j=1; j<maxn; ++j) { com[i][j]=(com[i-1][j-1]+com[i-1][j])%mod; } } } map<int ,int> T; ll factor[100][3]; int facnt; void get_factor(ll n) { facnt=0; for (int i=1; primes[i]<=n/primes[i]; ++i) { factor[facnt][2]=0; if(!(n%primes[i])) { factor[facnt][0]=primes[i]; facnt++; } while (!(n%primes[i])) { factor[facnt-1][2]++; n/=primes[i]; } } if(n!=1) { factor[facnt][0]=n; factor[facnt++][2]=1; } } int main () { int n; init(); while (~scanf("%d", &n)) { ll pro=1; T.clear(); int x; for (int i=0; i<n; ++i) { scanf("%d", &x); get_factor(x); for (int i=0; i<facnt; ++i) if(T[factor[i][0]])T[factor[i][0]]+=factor[i][2]; else T[factor[i][0]]=factor[i][2]; } //debug(pro); //debug(facnt); map<int, int>:: iterator it; ll tmp=1, ans=0; for (int i=1; i<=n; ++i) { //printf("%d\n", factor[i][2]); tmp=1; for (it=T.begin(); it!=T.end(); ++it) { tmp=(tmp*com[it->scd+n-i][n-i])%mod; } tmp=(tmp*com[n][i-1])%mod; if(i&1)ans=(tmp+ans)%mod; else ans=(ans-tmp+(ll)mod)%mod; //printf("%I64d %I64d\n", tmp, ans); } cout << ans%mod << endl; } return 0; } /* 5 3 3 3 3 4 3 3 3 3 2 3 3 3 4 4 4 */
线段树:加几个常数优化, 280s变781ms. 永远要保持着能水过的心态去优化。
#include <cstdio> #include <string.h> #include <algorithm> using namespace std; typedef long long ll; const int maxn=100000+123; int T[maxn*3]; int mx[maxn*3], mn[maxn*3]; int M, h; int bit(int x)/// get highest 1 in bit-number { if(x==0)return 0; int n=31; if((x>>16)==0){n-=16; x<<=16;} if((x>>24)==0){n-=8; x<<=8;} if((x>>28)==0){n-=4; x<<=4;} if((x>>30)==0){n-=2; x<<=2;} return n-(x>>31); } inline void merge (const int &x)//合并2个儿子的信息 { if(T[x<<1]==T[x<<1|1])T[x]=T[x<<1]; mx[x]=max(mx[x<<1], mx[x<<1|1]); mn[x]=min(mn[x<<1], mn[x<<1|1]); } void init(const int & x) { h=bit(x); M=1<<h; memset (T, -1, sizeof(T)); memset (mx, -1, sizeof(mx)); for (int i=0; i<x+M; ++i)mn[i]=0x7fffffff; for (int i=M; i<x+M; ++i) scanf("%d", &T[i]), mx[i]=T[i], mn[i]=T[i]; for (int i=M-1; i>0; --i) merge(i); } inline void Updata(const int & x, const int & v) { T[x]=v; mx[x]=v; mn[x]=v; // if(x<M) // { // T[x<<1]=v; // T[x<<1|1]=v; // } } void Down (int l, int r)// 区间下传信息, 实际上只是对2个开区间边界下传信息 { for (int i=h; i>0; --i) { int ll=l>>i, rr=r>>i; if(~T[ll]) { T[ll<<1]=T[ll<<1|1]=T[ll]; mx[ll<<1]=mx[ll<<1|1]=mx[ll]; mn[ll<<1]=mn[ll<<1|1]=mn[ll]; } if(~T[rr]) { T[rr<<1]=T[rr<<1|1]=T[rr]; mx[rr<<1]=mx[rr<<1|1]=mx[rr]; mn[rr<<1]=mn[rr<<1|1]=mn[rr]; } T[ll]=T[rr]=-1; } } void Change(int l, int r, int x) { int t=1; for (l+=M-1, r+=M+1, Down(l, r); l^r^1; l>>=1, r>>=1, t<<=1, merge(r), merge(l)) { if(~l&1) Updata(l^1, x); if( r&1) Updata(r^1, x); } while (l>1) { l>>=1; r>>=1; //printf("U l=%d r=%d\n", l, r); merge(l); if(l^r)merge(r); } } int getson (int L, int R, int v, int t, int rt) { //printf("G %d %d %d %d root==%d T=%d\n", L, R, l, r, rt, T[rt]); if(t<0)return 0; if(v>mx[rt] || v<mn[rt])return 0; if(T[rt]!=-1 && T[rt]!=v)return 0; int l=rt<<t, r=l^((1<<t)-1); if(L>r || R<l)return 0; if(T[rt]==v)return max(0, min(R, r)-max(L, l)+1); return getson(L, R, v, t-1, rt<<1)+getson(L, R, v, t-1, rt<<1|1); } int Request (int l, int r, int v) { return getson(l+M, r+M, v, h, 1); } void debug(int n) { for (int i=1; i<M+n; ++i) printf("%d%c", mn[i], ((i^1)&&(i^3)&&(i^7)&&(i^15)&&(i^31)&&(i^63))?' ':'\n'); puts(""); } int main () { int n, k; // freopen("1002.in", "r", stdin); // freopen("1002b.out", "w", stdout); while (~scanf("%d%d", &n, &k)) { init(n); while (k--) { int o, a, b, z; scanf("%d%d%d%d", &o, &a, &b, &z); //debug(n); if(o==1) { Change(a, b, z); } //debug(n); if(o==2) { printf("%d\n", Request(a, b, z)); } } } return 0; } /* 10 7 1 2 3 4 0 4 3 2 5 0 2 1 3 3 1 1 3 1 1 4 7 1 2 0 3 1 2 0 9 100 1 0 6 10 2 0 9 10 */