多校終於結束了, 開始從後往前整理
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
*/
4391 Paint The Wall
線段樹:加幾個常數優化, 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
*/