hdu 4391

传说中的分段哈希!!

看他说的那么玄乎(1002)http://page.renren.com/601081183/note/867254911

其实就是分成根号n段,然后乱搞啊。。。写了200行= = (50行头文件)。。弱爆了,太搓了

View Code
/*
ID: lxc9021
PROG: runround
LANG: C++
*/
/** @author starLeo
 *  Standard C++ Header File For Contests
 */
 //coding_is_fun!
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <fstream>
//#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <functional>
#include <utility> //pair
#include <map>
#include <set>
#include <list>
#include <deque>
#include <queue>
#include <stack>
#include <cctype>
#include <cstring>
//#include <malloc.h>
using namespace std;
#define R(x) scanf("%d",&(x)) //read int
#define RS(x) scanf("%s",(x)) //read string
#define PL(x) printf("%d\n",(x)) //println int
#define REP(i,n) for(int i(0),_n(n);i<_n;++i)
#define FOR(i,l,h) for(int i(l),_h(h);i<=_h;++i)
#define FORD(i,h,l) for(int i(h),_l(l);i>=_l;--i)
#define mem(a,b) memset((a),b,sizeof(a))
#define ST(a) (a).begin(),(a).end()
#define pb push_back
//#define oo (1234567890LL) // 64bits
#define oo (1<<29) // 32bits
//#define oo 9999999999.0 // Double
#define eps 1e-8
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
const double PI = acos(-1.0);
#ifndef StarLeo_DEBUG
    #define D(exp)
//    freopen("runround.in","r",stdin);
//    freopen("runround.out","w",stdout);
#else
    #define D(exp) (cout<<(#exp)<<" = "<<(exp)<<endl)
#endif

const int N = 333+10, H = 123, M = N*N;

struct Hash {
    int val,cnt;
    Hash *next;
};

int hash(int z) {
    return z*456%H;
}

int n,m,d,k;
int c[M];

struct Seg {
    int clr;
    Hash cnt[H];
    void down(int x) {
        mem(cnt,NULL);
        FOR(i,x*d,min(n,(x+1)*d)-1) {
            c[i]=clr;
            add(c[i],1);
        }
        clr=-1;
    }
    void add(int z,int d) {
        int ha=hash(z);
        if(cnt[ha].next==NULL) {
            Hash *p=new Hash;
            p->next=NULL;
            p->val=z;
            p->cnt=d;
            cnt[ha].next=p;
            return ;
        }
        Hash *p=&cnt[ha];
        while(p->next!=NULL) {
            if(p->next->val==z) {
                p->next->cnt+=d;
                if(p->next->cnt==0) {
                    Hash*del=p->next;
                    p->next=del->next;
                    delete del;
                }
                return;
            }
            p=p->next;
        }
        p=new Hash;
        p->next=cnt[ha].next;
        p->val=z;
        p->cnt=d;
        cnt[ha].next=p;
    }
    int ask(int z) {
        int ha=hash(z);
        Hash*p=cnt[ha].next;
        while(p) {
            if(p->val==z) return p->cnt;
            p=p->next;
        }
        return 0;
    }
};

Seg s[N];
void build() {
    k=0;
    for(int st=0;st<n;st+=d) {
        s[k].clr=-1;
        mem(s[k].cnt,NULL);
        FOR(i,st,min(st+d-1,n-1)) {
            s[k].add(c[i],1);
        }
        k++;
    }
}

int main()
{
    while(~R(n)) {
        R(m);
        d=ceil(sqrt(n*1.0));
        map<int,int> id;
        int all=0;
        REP(i,n) {
            int x; R(x);
            if(!id[x]) id[x]=++all;
            c[i]=id[x];
        }
        build();
        REP(i,m) {
            int a,l,r,z; scanf("%d%d%d%d",&a,&l,&r,&z);
            if(!id[z]) id[z]=++all;
            z=id[z];
            int x=l/d, y=r/d;
            if(a==1) {
                FOR(p,x+1,y-1) s[p].clr=z;
                if(x==y) {
                    if(s[x].clr!=z) {
                        if(s[x].clr>=0) s[x].down(x);
                        FOR(p,l,r) if(c[p]!=z) {
                            s[x].add(c[p],-1);
                            c[p]=z;
                            s[x].add(c[p],1);
                        }
                    }
                } else {
                    if(s[x].clr!=z) {
                        if(s[x].clr>=0) s[x].down(x);
                        FOR(p,l,min(n,(x+1)*d)-1) if(c[p]!=z) {
                            s[x].add(c[p],-1);
                            c[p]=z;
                            s[x].add(c[p],1);
                        }
                    }
                    if(s[y].clr!=z) {
                        if(s[y].clr>=0) s[y].down(y);
                        FOR(p,y*d,r) if(c[p]!=z) {
                            s[y].add(c[p],-1);
                            c[p]=z;
                            s[y].add(c[p],1);
                        }
                    }
                }
            } else {
                int ans=0;
                FOR(p,x+1,y-1) {
                    if(s[p].clr>=0) {
                        if(s[p].clr==z) {
                            ans+= p==(k-1)?(n-d*(k-1)):d;
                        }
                    } else {
                        ans+=s[p].ask(z);
                    }
                }
                if(x==y) {
                    if(s[x].clr>=0) {
                        if(s[x].clr==z) ans+= r-l+1;
                    } else {
                        FOR(p,l,r) ans+=c[p]==z;
                    }
                } else {
                    if(s[x].clr>=0) {
                        if(s[x].clr==z) ans+= min(n,(x+1)*d)-l;
                    } else {
                        FOR(p,l,min(n,(x+1)*d)-1) {
                            ans+=c[p]==z;
                        }
                    }
                    if(s[y].clr>=0) {
                        if(s[y].clr==z) ans+= r-y*d+1;
                    } else {
                        FOR(p,y*d,r) {
                            ans+=c[p]==z;
                        }
                    }
                }
                PL(ans);
            }

//            printf("---------------");
//            REP(j,n) printf("%d ",c[j]); puts("");
        }
    }

    return 0;
}
posted @ 2012-08-23 23:33  lxc902  阅读(423)  评论(0编辑  收藏  举报