2012 Multi-University Training Contest 10[hdu4390~4399]

多校终于结束了, 开始从后往前整理


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

*/







你可能感兴趣的:(优化,tree,iterator,query,merge,Training)