2014年8月28日 星期四

UVA 1449 Dominating Patterns

[AC自動機]

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<utility>
#include<map>
#include<set>
#include<queue>
using namespace std;
#define nullptr ((node*) ntpr)
void* ntpr;
class node{
public:
node(){
for(int lx = 0;lx < 26;lx++)
child[lx] = nullptr;
fail = nullptr;
exist = false;
wordindex = -1;
return;
}
~node(){
for(int lx = 0;lx < 26;lx++)
if(child[lx] != nullptr)
delete child[lx];
return;
}
node* child[26];
node* fail;
bool exist;
int wordindex;
};
class actrie{
public:
actrie(){
root = new node;
_sz = 0;
}
~actrie(){
delete root;
for(int lx = 0;lx < pats.size();lx++)
delete pats[lx];
return;
}
void insert(const char* inp){
node* prc = root;
for(int lx = 0;inp[lx];lx++){
int ch =  inp[lx] - 'a';
if(prc->child[ch] == nullptr)
prc->child[ch] = new node;
prc = prc->child[ch];
}
if(prc->exist == false){
prc->exist = true;
prc->wordindex = _sz;
char* instr = new char[strlen(inp)+2];
strcpy(instr, inp);
//printf("%s -> %d\n", inp, _sz);
pats.push_back(instr);
_sz++;
}else{
printf("%d\n", 1/0);
}
return;
}
void make(){
queue<node*> que;
que.push(root);
while(que.size()){
node* prc = que.front(); que.pop();
for(int lx = 0;lx < 26;lx++){
if(prc->child[lx] == nullptr) continue;
que.push(prc->child[lx]);
node* ff = prc->fail;
while(ff != nullptr and ff->child[lx] == nullptr)
ff = ff->fail;
if(ff != nullptr)
ff = ff->child[lx];
if(ff == nullptr) ff = root;
prc->child[lx]->fail = ff;
}
}
return;
}
int query(vector<char*>& re, const char* inp){
node* ptr = root;
int cnt[160]; for(int lx = 0;lx < 160;lx++)cnt[lx] = 0;
for(int lx = 0;inp[lx];lx++){
int ch = inp[lx]-'a';
while(ptr != root and ptr->child[ch] == nullptr)
ptr = ptr->fail;
ptr = ptr->child[ch];
if(ptr == nullptr) ptr = root;
node* prc = ptr;
while(prc != root){
if(prc->exist){
//printf("word index = %d\n", prc->wordindex);
cnt[prc->wordindex]++;
}
prc = prc->fail;
}
}
//printf("gather ok!\n");
int max_ind = 0;
for(int lx = 1;lx < pats.size();lx++)
if(cnt[lx] > cnt[max_ind])
max_ind = lx;
//if(cnt[max_ind] == 0) return 0;
for(int lx = 0;lx < pats.size();lx++){
if(cnt[max_ind] == cnt[lx])
re.push_back(pats[lx]);
}
return cnt[max_ind];
}
int size()const{return _sz;}
private:
node* root;
vector<char*> pats;
int _sz;
};
char buf[2000000];
int main()
{
int n;
for(;;){
scanf("%d", &n);
if(n == 0) break;
actrie act;
while(n--){
char inp[200];
scanf("%s", inp);
act.insert(inp);
}
act.make();
scanf("%s", buf);
vector<char*> gg;
printf("%d\n", act.query(gg, buf));
for(int lx = 0;lx < gg.size();lx++){
printf("%s\n", gg[lx]);
}
}
return 0;
}

2014年8月27日 星期三

UVAOJ 1676

[AC自動機]

為啥不早點AC QAQQQQQQ

是說覺得這種Online方式有點特別@@


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<utility>
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<functional>
#include<cstring>
using namespace std;
#define LL long long int
#define nullptr ((node*) nptr)
void* nptr;
struct StrCompare : public std::binary_function<const char*, const char*, bool> {
public:
    bool operator() (const char* str1, const char* str2) const
    { return std::strcmp(str1, str2) < 0; }
};
typedef map<const char* , int , StrCompare> DICT;
DICT dict;
int dict_query(const char* inp){
if(dict.count(inp) > 0)
return dict[inp];
//printf("add %s\n", inp);
char* nn = new char[strlen(inp)+2];
strcpy(nn, inp);
int sz = dict.size();
dict[nn] = sz;
return sz;
}
bool dict_check(const char* inp){
return(dict.count(inp) > 0);
}
void dict_clear(){
for(DICT::iterator it = dict.begin();it != dict.end();it++)
delete[] it->first;
dict.clear();
return;
}
class node{
public:
node(){
child[0] = nullptr, child[1] = nullptr;
//fail[0] = nullptr, fail[1] = nullptr;
fail = nullptr;
exist = false;
wordindex = -1;
countpoint = 0;
return;
}
~node(){
for(int lx = 0;lx < 2;lx++){
if(child[lx] != nullptr) delete child[lx];
//if(fail[lx] != nullptr) delete fail[lx];
}
return;
}
node* child[2];
node* fail;
bool exist;
int countpoint;
int wordindex;
};

class actrie{
public:
actrie(){
root = new node;
maked = false;
return;
}
void insert(const char *inp){
node* prc = root;
for(int lx =0;inp[lx];lx++){
char ch = inp[lx] - '0';
if(prc->child[ch] == nullptr)
prc->child[ch] = new node;
prc = prc->child[ch];
}
prc->exist = true;
prc->wordindex = dict_query(inp);
return;
}
~actrie(){
delete root;
}
void clear(){
delete root;
root = new node;
maked = false;
return;
}
void make(){
if(maked) return;
queue<node*> que;
root->fail = nullptr;
que.push(root);
while(que.size()){
node* prc = que.front(); que.pop();
for(int lx = 0;lx < 2;lx++){
if(prc->child[lx] == nullptr) continue;
node* nn = prc->fail;
while(nn != nullptr and nn->child[lx] == nullptr)
nn = nn->fail;
if(nn != nullptr)
nn = nn->child[lx];
if(nn == nullptr)
nn = root;
prc->child[lx]->fail = nn;
prc->child[lx]->countpoint = nn->countpoint + prc->child[lx]->exist;
que.push(prc->child[lx]);
}
}
maked = true;
return;
}
LL query(const char* inp){
//if(maked == false) printf("%d\n", 1/0);
//printf("q %s\n", inp);
LL cnt = 0;
node* prc = root;
set<int> counted;
for(int lx = 0;inp[lx];lx++){
int ch = inp[lx]=='1';
while(prc != root and prc->child[ch] == nullptr)
prc = prc->fail;
prc = prc->child[ch];
if(prc == nullptr) prc = root;
cnt += prc->countpoint;
/*node* ptr = prc;
while(ptr != root and counted.count(ptr->wordindex)==0){
cnt += ptr->exist;
if(ptr->wordindex != -1)
counted.insert(ptr->wordindex);
ptr = ptr->fail;
}*/
}
return cnt;
}
void print(){
printf("{");
_printnode(root);
printf("}\n");
return;
}
private:
node* root;
bool maked;
void _printnode(node* rt){
printf("(%d = %d,%d)[ ", rt->wordindex, rt->exist, rt->countpoint);
for(int lx = 0;lx < 2;lx++)
if(rt->child[lx] != nullptr)
printf("%d:", lx), _printnode(rt->child[lx]);
printf("]");
return;
}
};
class ACBST{
public:
ACBST(){
memset(comp, false, sizeof(comp));
comp[base+1] = true;
_size = 0;
}
void setbase(int n){
base = (1<<(int)(ceil(log2(n+3))))-1;
return;
}
~ACBST(){clear();};
void clear(){
for(int lx = 0;lx < line.size();lx++)
delete line[lx];
for(int lx = 1;lx <= line.size()+1+base;lx++)
comp[lx] = 0;
for(int lx = 1;lx <= line.size()+1+base;lx++)
act[lx].clear();
comp[base+1] = true;
line.clear();
return;
}
void add(const char *inp){
if(dict_check(inp) == true) return;
char* ch = new char[strlen(inp)+2];
dict_query(inp);
strcpy(ch,inp);
line.push_back(ch);
comp[line.size()+1+base] = true;
for(int prc = line.size() + 1 + base;prc;prc>>=1)
act[prc].insert(inp);
act[line.size() + 1 + base].make();
//printf("make %d\n", line.size()+1+base);
for(int prc = (line.size()+1+base)>>1;prc;prc>>=1)
if(comp[prc*2] and comp[prc*2+1] and not comp[prc]){
act[prc].make();
comp[prc] = true;
//printf("make %d\n", prc);
}
//printf("inp = %s = ch = %s\n", inp, ch);

return;
}
/*void make(){
base = (1<<(int)(ceil(log2(line.size()+2))))-1;
for(int lx = 0;lx < line.size();lx++)
for(int prc = base+1 + lx+1;prc;prc>>=1)
act[prc].insert(line[lx]);
for(int lx = 1;lx <= base+line.size()+1;lx++)
act[lx].make();
for(int lx = 1;lx <= base+line.size()+1;lx++)
act[lx].print();
return;
}*/
LL query(const char* inp){
if(size() == 0) return 0;
int a = 2;
int b = size()+1;
LL cnt = 0;
int nds[40], ndcnt = 0;
for(a += base-1, b += base+1; a^b^1;a>>=1, b>>=1){
if(~a&1){
//printf("q node at a%d\n", a^1);
nds[ndcnt++] = a^1;
cnt += act[a^1].query(inp);
}
if(b&1){
//printf("%d\n", 1/0);
//printf("q node at b%d\n", b^1);
nds[ndcnt++] = b^1;
cnt += act[b^1].query(inp);
}
}
return cnt;
}
int size(){return line.size();};
private:
int _size;
vector<char*> line;
actrie act[400005];
bool comp[400005];
int base;
};
char gstr[5000005];
ACBST acbst;
struct command{
char* str;
int qsz;
}cmds[100005]; int cmd_cnt;
void swapstr(char *inp, int a, int b){
for(int lx = 0;a+lx < b-lx;lx++){
char tmp = inp[a+lx];
inp[a+lx] = inp[b-lx];
inp[b-lx] = tmp;
}
return;
}
int main()
{int T;scanf("%d", &T);
for(int lt = 1;lt <= T;lt++){
dict_clear();
acbst.clear();
cmd_cnt = 0;
int n;scanf("%d", &n);
acbst.setbase(n);
LL last = 0;
printf("Case #%d:\n", lt);
while(n--){
scanf("%s", gstr);
int len = strlen(gstr+1);
int _last = (int)(last%(LL)len);
swapstr(gstr+1, 0, len-1);
swapstr(gstr+1, 0, len-_last-1);
swapstr(gstr+1, len-_last, len-1);
//printf("operate str = %s\n", gstr+1);
if(gstr[0] == '+'){
acbst.add(gstr+1);
}else{
LL ans = acbst.query(gstr+1);
printf("%I64d\n", ans/(ans>=0));
last = ans;
}
}
}return 0;}

2014年8月26日 星期二

HDU 2222 Keywords Search

[AC 自動機]

/OwO/就是要用nullptr

#include<queue>
#include<cstdio>
using namespace std;
#define nullptr (node*) nptr
void* nptr;
class node{
public:
    node(){
        for(int lx = 0;lx < 27;lx++)
            child[lx] = nullptr;
        failed = nullptr;
        n = 0;
        reset();
        return;
    }
    ~node(){
        for(int lx = 0;lx < 27;lx++)
            if(child[lx] != nullptr)
                delete child[lx];
        return;
    }
    void reset(){
        counted = false;
        return;
    }
    node* child[27];
    node* failed;
    int n;
    bool counted;
};
class actrie{
public:
    actrie(){ root = new node;}
    void insert(const char* inp){
        node* prc = root;
        for(int lx = 0;inp[lx];lx++){
            int ch = inp[lx] - 'a';
            if(prc->child[ch] == nullptr){
                prc->child[ch] = new node;
            }
            prc = prc->child[ch];
        }
        prc->n++;
        return;
    }
    void make(){
        queue<node*> que;
        root->failed = nullptr;
        root->counted = true;
        que.push(root);
        while(que.size()){
            node* prc = que.front(); que.pop();
            for(int lx = 0;lx < 26;lx++){
                if(prc->child[lx] == nullptr) continue;
                node* nn = prc->failed;
                while(nn != nullptr and nn->child[lx] == nullptr){
                    nn = nn->failed;
                }
                if(nn != nullptr)
                    nn = nn->child[lx];
                if(nn == nullptr)
                    nn = root;
                prc->child[lx]->failed = nn;
                que.push(prc->child[lx]);
            }
        }
        return;
    }
    int query(const char* inp)const{
        int cnt = 0;
        node* ptr = root;
        for(int lx = 0;inp[lx];lx++){
            int ind = inp[lx]-'a';
            while(ptr->child[ind] == nullptr and ptr != root)
                ptr = ptr->failed;
            ptr = ptr->child[ind];
            if(ptr == nullptr) ptr = root;
            node* prc = ptr;
            while(not prc->counted){
                cnt += prc->n;
                prc->counted = true;
                prc->n = -1; //
                prc = prc->failed;
            }
        }
        return cnt;
    }
    ~actrie(){delete root;}
private:
    node* root;
};
char dest[1000005];
int main(){
int T;scanf("%d", &T);while(T--){
    int n;scanf("%d", &n);
    actrie ac;
    for(int lx = 0;lx < n;lx++){
        char inp[55];scanf("%s", inp);
        ac.insert(inp);
    }
    ac.make();
    scanf("%s", dest);
    printf("%d\n", ac.query(dest));
}return 0;}

2014年8月19日 星期二

POJ 2411 Mondriaan's Dream

[DP]
JzDP

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<utility>
#include<map>
#include<set>
#define LL long long int
using namespace std;
bool checkeven1(int a){
int c = 0;
while(a){
if(a&1)
c = 1-c;
else
if(c) return false;
a>>=1;
}
if(c) return false;
return true;
}
int main()
{
int h, w;
while(scanf("%d %d", &h, &w) == 2){
if((h == 0) and (w == 0)) break;
LL dp[13][1<<12];
for(int lx = 0;lx < (1<<w);lx++)
dp[0][lx] = (LL)checkeven1(lx);
for(int lh = 1;lh <= h;lh++){
for(int lx = 0;lx < (1<<w);lx++){
dp[lh][lx] = 0;
for(int ly = 0;ly < (1<<w);ly++)
if((lx|ly) == (1<<w)-1 and checkeven1(lx&ly))
dp[lh][lx] += dp[lh-1][ly];
}
}
printf("%lld\n", dp[h][0]);
}
return 0;
}

POJ 3254 Corn Fields

http://poj.org/problem?id=3254
[DP]

覺得難過QQ

只好來寫水題QQ

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<utility>
#include<map>
#include<set>
#define MOD 100000000
using namespace std;
int main()
{
int M, N;scanf("%d %d", &M, &N);
int line[100];
for(int lx = 0;lx < M;lx++){
line[lx] = 0;
for(int ly = 0;ly < N;ly++){
int inp;scanf("%d", &inp);
line[lx] = line[lx]*2 + inp;
}
}
int dp[14][1<<12];
for(int lx = 0;lx < (1<<N);lx++)
dp[0][lx] = ((lx|line[0])^line[0]) == 0 and ((lx>>1)&(lx)) == 0;
for(int lm = 1;lm < M;lm++){
for(int lx = 0;lx < (1<<N);lx++)
if(((lx|line[lm])^line[lm]) == 0 and ((lx>>1)&(lx)) == 0)
for(int ly = 0;ly < (1<<N);ly++){
dp[lm][lx] += dp[lm-1][ly]*((lx&ly) == 0);
dp[lm][lx] %= MOD;
}
}
int cnt = 0;
for(int lx = 0;lx < (1<<N);lx++)
cnt = (cnt +dp[M-1][lx])%MOD;
printf("%d\n", cnt);
return 0;
}

2014年8月16日 星期六

SPOJ Count on a tree 2

終於把這神奇的題目搞出來惹(汗

121633702014-08-16 17:03:17藍雪Count on a tree IIaccepted 40.9573MC++
4.3.2

四千大大神威<(_ _)>
經四千大大指導>w<

終於突破各種WA

超級有成就感的><

總之這題就是
把樹攤開後,把每個區間射到一個平面上,然後用平方分解的方式遍歷,可以保證複雜度在O(n*q^0.5)

是說還有看到強制在線的題目QQ 好可怕><

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<utility>
#include<map>
#include<set>
#include<cmath>
#define NN 40005
#define QQ 100005
using namespace std;
void assertTLE(bool check){
if(check == false)
while(1);
return;
}
void assertRE(bool check){
if(check == false)
printf("%d\n", 1/0);
return;
}
const int INFVAL = 100000000;
class RMQ{
public:
RMQ(){};
void setup(int _n, int *a){
all = _n;
/*printf("\nRMQ SETUP:\n");
for(int lx = 0;lx < _n;lx++)
printf("%d ", a[lx]);
puts("");*/
for(int lx = 0;lx < _n;lx++) value[lx] = a[lx];
for(int lx = 0;lx < _n;lx++) sp[lx][0] = lx;
for(int lx = 1;(1<<lx) < (_n+2);lx++){
for(int ly = 0;ly+(1<<lx)-1 < _n;ly++){
int m = ly + (1<<(lx-1));
sp[ly][lx] = minindex(sp[ly][lx-1], sp[m][lx-1]);
}
}
return;
}
int ask(int a, int b){
if(b < a) a^=b^=a^=b;
//assertRE(a<=b);
int k = (int)(log2(b-a+1));
//assertRE(a+(1<<k) - 1 >= b - (1<<k));
assertRE(a+(1<<k) - 1 <= b);
return minindex(sp[a][k], sp[b-(1<<k)+1][k]);
}
private:
int sp[8*NN][50];
int value[8*NN];
int all;
int minindex(int ind1, int ind2){
return (value[ind1]<value[ind2])? ind1: ind2;
}
};
int an[NN];
int tree[NN*2];
int tlca[NN*8];
int thei[NN*8];
int nodhei[NN];
int n, sqrtn; int tlcalen = 0;
pair<int,int> nodmap[NN];
int lcamap[NN];
typedef struct _query{ int x, y; int id;int ans;int na, nb;}query;
//void printq(query a){printf("q: nod=%d->%d rang=%d->%d\n",a.na, a.nb, a.x, a.y);return;}
query qs[QQ];
bool operator<(query a, query b){
if(a.x/sqrtn != b.x/sqrtn) return a.x/sqrtn < b.x/sqrtn;
return a.y < b.y;
}
struct _cmp_id{bool operator()(query a, query b){return a.id<b.id;}}cmp_id;
vector<int> link[NN];
RMQ LCA;
int _dfscnt = 0;
void dfs(int fat, int chd){
//printf("%d ", chd+1);
nodmap[chd].first = _dfscnt;
tree[_dfscnt++] = chd;
lcamap[chd] = tlcalen;
tlca[tlcalen++] = chd;
for(int lx = 0;lx < link[chd].size();lx++){
if(fat == link[chd][lx]) continue;
nodhei[link[chd][lx]] = nodhei[chd]+1;
dfs(chd, link[chd][lx]);
tlca[tlcalen++] = chd;
//printf("%d ", chd+1);
}
nodmap[chd].second = _dfscnt;
tree[_dfscnt++] = chd;
//printf("%d ", chd);
return;
}
//set<int>nodvis;
//map<int, int>valcnt;
bool nodvis[NN];
int valcnt[NN], valsz;
int autolca = -1;
int segleft = 0, segright = 0;
void init(int _n){
valsz = 0;
for(int lx = 0;lx < NN;lx++){
nodvis[lx] = false;
valcnt[lx] = 0;
}
return;
}
void writelca(int anc){ autolca = anc; return;}
void write(int a){
//printf("visit %d, val = %d\n", a, an[a]);
//assertRE(an[a]<=40000);
if(nodvis[a] == false){
nodvis[a] = true;
valcnt[an[a]]++;
if(valcnt[an[a]] == 1) valsz++;
}else{
nodvis[a] = false;
assertRE(valcnt[an[a]] > 0);
valcnt[an[a]]--;
if(valcnt[an[a]] == 0){
valsz--;
}
}
return;
}
int read(){
/*printf("read seg => lca = %d\n", autolca);
for(int lx = 0;lx < 10;lx++)
if(valcnt[lx] != 0)
printf("getval = %d\t", lx);
printf("\n");*/
int _sz = valsz;
if(autolca != -1)
_sz += valcnt[an[autolca]]==0;
return _sz;
}
int main()
{
int n, m;scanf("%d %d", &n, &m);
map<int, int> jizz;
for(int lx = 0;lx < n;lx++)
scanf("%d", an+lx);
// jizzan
for(int lx = 0;lx < n;lx++){
if(jizz.count(an[lx]) == 0){
int gtsz = jizz.size();
jizz[an[lx]] = gtsz;
an[lx] = gtsz;
}else
an[lx] = jizz[an[lx]];
//printf("%d ", an[lx]);
}
//printf("\n");
for(int lx = 0;lx < n-1;lx++){
int a,b;scanf("%d %d", &a,&b);
link[a-1].push_back(b-1);
link[b-1].push_back(a-1);
}
_dfscnt = 0;
nodhei[0] = 0;
dfs(-1, 0);
for(int lx = 0;lx < tlcalen;lx++)
thei[lx] = nodhei[tlca[lx]];
LCA.setup(tlcalen, thei);
/*printf("\npair result:\n");
for(int lx = 0;lx < n;lx++)
printf("%d -> %d, %d\n", lx, nodmap[lx].first, nodmap[lx].second);*/
for(int lx = 0;lx < m;lx++){
int na, nb;scanf("%d %d", &na, &nb); na--; nb--;
qs[lx].id = lx; qs[lx].na = na, qs[lx].nb = nb;
//printf("ask %d,%d -> %d,%d\n", nodmap[na].first, nodmap[na].second, nodmap[nb].first, nodmap[nb].second);
if((nodmap[na].first < nodmap[nb].first) and (nodmap[nb].second < nodmap[na].second)){
qs[lx].x = nodmap[na].first, qs[lx].y = nodmap[nb].first;
//printf("trig1\n");
}else if((nodmap[nb].first < nodmap[na].first) and (nodmap[na].second < nodmap[nb].second)){
qs[lx].x = nodmap[nb].first, qs[lx].y = nodmap[na].first;
//printf("trig2\n");
}else if(nodmap[na].second < nodmap[nb].first){
qs[lx].x = nodmap[na].second, qs[lx].y = nodmap[nb].first;
//printf("trig3\n");
}else if(nodmap[nb].second < nodmap[na].first){
qs[lx].x = nodmap[nb].second, qs[lx].y = nodmap[na].first;
//printf("trig4\n");
}else if(na == nb){
qs[lx].x = nodmap[nb].first, qs[lx].y = nodmap[nb].second;
}
}
//assertTLE(m >= 1);
sqrtn = (int)(n/sqrt(m));
sort(qs, qs+m);
init(n);
/*for(int lx = 0;lx < m;lx++)
printq(qs[lx]);*/
for(int lx = qs[0].x;lx <= qs[0].y;lx++)
write(tree[lx]);
writelca(tlca[LCA.ask(lcamap[qs[0].na], lcamap[qs[0].nb])]);
segleft = qs[0].x, segright = qs[0].y;
qs[0].ans = read();
for(int lxx = 1;lxx < m;lxx++){
if(segleft < qs[lxx].x){
for(int lx = segleft;lx <= qs[lxx].x-1;lx++){
write(tree[lx]);
}
}else if(segleft > qs[lxx].x){
for(int lx = segleft-1;lx >= qs[lxx].x;lx--){
write(tree[lx]);
}
}
if(segright < qs[lxx].y){
for(int lx = segright+1;lx <= qs[lxx].y;lx++){
write(tree[lx]);
}
}else if(segright > qs[lxx].y){
for(int lx = segright;lx >= qs[lxx].y+1;lx--){
write(tree[lx]);
}
}
segleft = qs[lxx].x, segright = qs[lxx].y;
writelca(tlca[LCA.ask(lcamap[qs[lxx].na], lcamap[qs[lxx].nb])]);
qs[lxx].ans = read();
}
sort(qs, qs+m, cmp_id);
for(int lx = 0;lx < m;lx++){
//printq(qs[lx]);
printf("%d\n", qs[lx].ans);
}
return 0;
}
/*
testdata:
8
5
1 3 4 -1 2 1 2 9
1 2 2 3 3 4
1 5 5 6
5 7 7 8
2 6
3 6
1 8
3 7
1 6
*/

2014年8月13日 星期三

UVA 11039

greedy
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
int an[500005];
int __abs(int x){
    if(x > 0) return x;
    return -x;
}
struct cp{
    bool operator()(int a, int b){
        return __abs(a) < __abs(b);
    }
}CP;
int main(){
    int T;scanf("%d", &T);
    while(T-->0){
        int n;scanf("%d", &n);
        for(int lx = 0;lx < n;lx++)
            scanf("%d", an+lx);
        sort(an, an + n, CP);
        int neg = 0, pos = 0;
//        int neg_ind = -1, pos_ind = -1;
        for(int lx =0;lx < n;lx++){
            if(an[lx] < 0) pos = max(pos, neg+1);
            if(an[lx] > 0) neg = max(neg, pos+1);
        }
        printf("%d\n", max(neg, pos));
    }
    return 0;
}

2014年8月12日 星期二

kth number RMQ revisit

http://poj.org/problem?id=2104

O((N+M)logN)

用ㄎㄠ線段樹:3

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<utility>
#include<map>
#define min(x,y) (((x)>(y)) ? (y):(x))
#define max(x,y) (((x)>(y)) ? (x):(y))
#define NN 100015
using namespace std;
typedef struct _node{ int left_ind; int right_ind; int count; }node;
int an[NN];int n;
node tree[NN*40]; /** 2N + NlgN **/
int sz =0;
int tline[NN];
int tline_sz;
int cownod[NN];
int _step = 0;
void test_step(){_step++; if(_step/3000 >= 1000) printf("%d\n", 1/0);}
void _assert(bool t){if(t == false)printf("%d", 1/0); return;}
inline int make(int l, int r){
test_step();
int prc_ind = sz; sz++;
tree[prc_ind].count = 0;
tree[prc_ind].left_ind = -9999999, tree[prc_ind].right_ind =-9999999;
if(l >= r) return prc_ind;
int mid = (l+r)>>1;
tree[prc_ind].left_ind = make(l, mid);
tree[prc_ind].right_ind = make(mid+1, r);
return prc_ind;
}
int jizz(int rt_ind, int jiz_ind, int l, int r){
_assert(rt_ind>=0);
test_step();
int newrt_ind = sz; sz++;
tree[newrt_ind] = tree[rt_ind];
tree[newrt_ind].count++;
if(l == r) return newrt_ind;
_assert(jiz_ind >= l and jiz_ind <= r);
int mid = (l+r)>>1;
// left = l ~ mid, right = mid+1 ~ r
if(jiz_ind <= mid){ //left
int newleft_ind = jizz(tree[rt_ind].left_ind, jiz_ind, l, mid);
tree[newrt_ind].left_ind = newleft_ind;
}else{
int newright_ind = jizz(tree[rt_ind].right_ind, jiz_ind, mid+1, r);
tree[newrt_ind].right_ind = newright_ind;
}
return newrt_ind;
}

inline int read(int lrt, int rrt, int k){
//printf("read [%d~%d]\n", tleft, tright);
int tleft = 0, tright = tline_sz+1;
while(tleft < tright){
test_step();
int tmid = (tleft+tright)>>1;
int leftcnt = tree[tree[rrt].left_ind].count - tree[tree[lrt].left_ind].count;
if(k <= leftcnt){
lrt = tree[lrt].left_ind, rrt = tree[rrt].left_ind;
tright = tmid;
}else{
lrt = tree[lrt].right_ind, rrt = tree[rrt].right_ind;
tleft = tmid+1;
k -= leftcnt;
}
}
return tleft;
}
void printtree(int rt){
if(tree[rt].left_ind == -1){
printf("%d ", tree[rt].count);
return;
}
//printf(" %d:{", tree[rt].count);
printtree(tree[rt].left_ind);
printtree(tree[rt].right_ind);
//printf("}");
}
int main()
{
int m;scanf("%d %d", &n, &m);
for(int lx = 0;lx < n;lx++) scanf("%d", an+lx), tline[lx] = an[lx];
sort(tline, tline+n);
tline_sz = n;
//printf("%d\n", tline_sz);
map<int, int> arctline;
_assert(tline_sz == n);
cownod[0] = make(0, tline_sz+1);
for(int lx = 0;lx < n;lx++){
int pos = lower_bound(tline,tline+n,an[lx]) - tline;
cownod[1+lx] = jizz(cownod[lx], pos, 0, tline_sz+1);
}
/*for(int lx = 0;lx <= n;lx++){
printtree(cownod[lx]);puts("");
}*/
while(m-->0){
int ll, rr, k;scanf("%d %d %d", &ll, &rr, &k);
printf("%d\n", tline[read(cownod[ll-1], cownod[rr], k)]);
}
return 0;
}

2014年8月5日 星期二

POJ 2104 kth-number

http://poj.org/problem?id=2104

第一次寫.....
O(N(lgN)^2 + M(lgN)^3)

過惹,沒被Tㄟ,好開心~

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<utility>
#include<cmath>
//#define min(x,y) (((x)>(y)) ? (y):(x))
//#define max(x,y) (((x)>(y)) ? (x):(y))
#define N 100005
#define INF (1000*1000*1000 + 1)
using namespace std;
vector<int> tree[4*N];
int nodecnt[4*N];
int base;
int n;
int an[N];
void setup(){
base = (1<<(int)(ceil(log2(n+2)))) - 1;
for(int lx = 0;lx < n;lx++){
tree[base + 1 + lx + 1].push_back(an[lx]);
nodecnt[base + 1 + lx + 1] = 1;
}
tree[base + 1].push_back(INF);
nodecnt[base + 1] = 0;
for(int lx = n;lx <= base;lx++){
tree[base + 1 + lx + 1].push_back(INF);
nodecnt[base + 1 + lx + 1] = 0;
}
for(int lx = base;lx;lx--){
for(int ll = 0;ll < tree[2*lx].size();ll++)
tree[lx].push_back(tree[2*lx][ll]);
for(int ll = 0;ll < tree[2*lx+1].size();ll++)
tree[lx].push_back(tree[2*lx+1][ll]);
nodecnt[lx] = nodecnt[2*lx] + nodecnt[2*lx+1];
sort(tree[lx].begin(), tree[lx].end());
/*printf("node %d:\n", lx);
for(int ll = 0;ll < tree[lx].size();ll++)
if(tree[lx][ll] >= INF)
printf("inf ");
else
printf("%03d ", tree[lx][ll]);
printf("\n");*/
}
return;
}
int query(int a, int b, int k){
a++, b++;
int seg[100], segcnt = 0;
for(a+=base-1,b+=base+1; a^b^1;a>>=1, b>>=1){
if(~a&1){
seg[segcnt] = a^1;
segcnt++;
//printf("get seg: %d\n", a^1);
}
if(b&1){
seg[segcnt] = b^1;
segcnt++;
//printf("get seg: %d\n", b^1);
}
}
int max_ele = -INF, min_ele = INF;
for(int lx = 0;lx < segcnt;lx++){
max_ele = max(max_ele, tree[seg[lx]][0]);
max_ele = max(max_ele, tree[seg[lx]][tree[seg[lx]].size()-1]);
min_ele = min(min_ele, tree[seg[lx]][0]);
min_ele = min(min_ele, tree[seg[lx]][tree[seg[lx]].size()-1]);
}
while(min_ele < max_ele){
//printf("bsh %d -> %d\n", min_ele, max_ele);
int test = (min_ele + max_ele)/2;
int check = 1;
bool found = false;
for(int lx = 0;lx < segcnt;lx++){
int getindex = lower_bound(tree[seg[lx]].begin(), tree[seg[lx]].end(), test)-tree[seg[lx]].begin();
check += getindex;
found = found or  (tree[seg[lx]][getindex] == test);
}
if(check == k){
if(found)
return test;
else{
min_ele = test+1;
//printf("giz\n");
}
}else if(check > k) max_ele = test - 1;
else if(check < k) min_ele = test + 1;
}
return min_ele;
}
int main()
{
int m;scanf("%d %d", &n, &m);
for(int lx = 0;lx < n;lx++)
scanf("%d", an+lx);
setup();
while(m--){
int a, b, k;scanf("%d %d %d", &a, &b, &k);
printf("%d\n", query(a, b, k));
}
return 0;
}

2014年8月3日 星期日

UVA p920 Sunny Mountain

掃描線%%%

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<utility>
#include<cmath>
#define min(x,y) (((x)>(y)) ? (y):(x))
#define max(x,y) (((x)>(y)) ? (x):(y))
using namespace std;
struct point{ int x, y;};
struct ccc{
bool operator()(point a, point b){return a.x < b.x;
}
}cccc;
int main()
{
int T;scanf("%d", &T);
while(T-->0){
int n; scanf("%d", &n);
point ps[200];
for(int lx = 0;lx < n;lx++)
scanf("%d %d", &ps[lx].x, &ps[lx].y);
sort(ps, ps+n , cccc);
double sum = 0;
double px = ps[n-1].x, py = ps[n-1].y;
for(int lx = n-2;lx >= 0;lx--){
if(ps[lx].y > py){
sum += (ps[lx].y-py) * sqrt( (ps[lx].x - ps[lx+1].x)*(ps[lx].x - ps[lx+1].x) +
(ps[lx].y - ps[lx+1].y)*(ps[lx].y - ps[lx+1].y))/(ps[lx].y-ps[lx+1].y);
py = ps[lx].y;
px = ps[lx].x;
}
}
printf("%.2f\n", sum);
}
return 0;
}