顯示具有 UVA 標籤的文章。 顯示所有文章
顯示具有 UVA 標籤的文章。 顯示所有文章

2015年6月6日 星期六

UVA 11255 - Necklace

第一次練Burnside@@
主要是把每次fix point的個數算出來就好惹。
雖然複雜度可以壓到O(40^3 + N*(a+b+c))但反正會過XD

1. 算
2. 把答案存起來XD

#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <unordered_map>

using namespace std;

typedef long long int int64;

struct Key{int a, b, c; Key(int _a, int _b, int _c):a(_a), b(_b), c(_c){return;}};
bool operator==(const Key& p, const Key& q){return p.a == q.a and p.b == q.b and p.c == q.c;}
struct KeyHash{size_t operator()(const Key& key)const{ return (hash<int>()(key.a)<<14)^(hash<int>()(key.b)<<7)^hash<int>()(key.c);}};

void dumpvec(vector<int>& vec){printf("vec:");for(int ii : vec) printf(" %d", ii);printf("\n");return;}

struct Ans{int v[3]; Ans(int a, int b, int c){v[0] = a, v[1] = b, v[2] = c; sort(v, v+3);return;}};
bool operator==(const Ans& p, const Ans& q){return p.v[0] == q.v[0] and p.v[1] == q.v[1] and p.v[2] == q.v[2];}
struct AnsHash{size_t operator()(const Ans& a)const{return (hash<int>()(a.v[0])<<14)^(hash<int>()(a.v[1])^7)^hash<int>()(a.v[2]);}};

int main(){
    int N; scanf("%d", &N);
    unordered_map<Ans, int64, AnsHash> anstab;
    while(N--){
        int a, b, c;
        scanf("%d %d %d", &a, &b, &c);

        if(anstab.count(Ans(a, b, c))){
            printf("%lld\n", anstab[Ans(a, b, c)]);
            continue;
        }

        int64 ans = 0;
        int n = a+b+c;
       
        // 0-turn
        for(int tptr = 0;tptr < n;tptr++){
            bool vis[40] = {0};
            vector<int> vec;
            for(int lx = 0;lx < n;lx++){
                int cc = 0;
                int ptr = lx;
                while(!vis[ptr]){
                    vis[ptr] = 1;
                    cc++;
                    ptr = (ptr+tptr)%n;
                }
                if(cc) vec.push_back(cc);
            }
            unordered_map<Key, int64, KeyHash> bfs[2];
            bfs[0][Key(a, b, c)] = 1;
            int pp = 0;
            for(int dt : vec){
                bfs[pp^1].clear();
                for(auto it : bfs[pp]){
                    Key k = it.first; int64 val = it.second;
                    if(k.a >= dt) bfs[pp^1][Key(k.a-dt, k.b, k.c)] += val;
                    if(k.b >= dt) bfs[pp^1][Key(k.a, k.b-dt, k.c)] += val;
                    if(k.c >= dt) bfs[pp^1][Key(k.a, k.b, k.c-dt)] += val;
                }
                pp ^= 1;
            }
            ans += (int64)bfs[pp][Key(0, 0, 0)];
        }
       
        // 1-turn
        for(int tptr = 0;tptr < n;tptr++){
            bool vis[40] = {0};
            vector<int> vec;
            for(int lx = 0;lx < n;lx++){
                int cc = 0;
                int ptr = lx;
                while(!vis[ptr]){
                    vis[ptr] = 1;
                    ptr = (n-1-ptr+tptr)%n;
                    cc++;
                }
                if(cc) vec.push_back(cc);
            }
            unordered_map<Key, int64, KeyHash> bfs[2];
            bfs[0][Key(a, b, c)] = 1;
            int pp = 0;
            for(int dt : vec){
                bfs[pp^1].clear();
                for(auto it : bfs[pp]){
                    Key k = it.first; int64 val = it.second;
                    if(k.a >= dt) bfs[pp^1][Key(k.a-dt, k.b, k.c)] += val;
                    if(k.b >= dt) bfs[pp^1][Key(k.a, k.b-dt, k.c)] += val;
                    if(k.c >= dt) bfs[pp^1][Key(k.a, k.b, k.c-dt)] += val;
                }
                pp ^= 1;
            }
            ans += (int64)bfs[pp][Key(0, 0, 0)];
        }
       
        anstab[Ans(a, b, c)] = ans/2/n;

        printf("%lld\n", ans/2/n);
    }
    return 0;
}

2015年3月11日 星期三

UVA 10652 - Board Wrapping

模板題
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cmath>

using namespace std;

const double PI = acos(-1);
const double eps = 1e-10;
int sgn(double a){ return a<-eps ? -1 : a>eps;}

class pt{
public:
    double x, y;
    pt(double _x = 0, double _y = 0):x(_x), y(_y){}
    pt rotate(double j){
        const double s = sin(j), c = cos(j);
        return pt(x*c-y*s,x*s+y*c);
    }    
};

bool operator==(const pt& a, const pt& b){return sgn(a.x-b.x) == 0 and sgn(a.y-b.y) == 0;}
pt operator-(const pt& a, const pt& b){return pt(a.x - b.x, a.y - b.y);}
pt operator+(const pt& a, const pt& b){return pt(a.x + b.x, a.y + b.y);}
double operator^(const pt& a, const pt& b){return a.x*b.y - a.y*b.x;}

struct cpbyx{bool operator()(pt a, pt b){return a.x == b.x ? a.y < b.y : a.x < b.x;}};
vector<pt> ConvexHull(vector<pt> inp){
    vector<pt> bt_ret, tp_ret;
    sort(inp.begin(), inp.end(), cpbyx());
    auto it = unique(inp.begin(), inp.end());
    inp.resize(distance(inp.begin(), it));
    for(int lx = 0;lx < inp.size();lx++){
        pt v = inp[lx];
        for(int ly = (int)bt_ret.size()-1;ly>=1;ly--){
            if(sgn((bt_ret[ly]-bt_ret[ly-1])^(v-bt_ret[ly])) <= 0){
                bt_ret.pop_back();
            }else
                break;
        }
        bt_ret.push_back(v);
    }
    for(int lx = (int)inp.size()-1;lx>=0;lx--){
        pt v = inp[lx];
        for(int ly = ((int)tp_ret.size())-1;ly>=1;ly--)
            if(sgn((tp_ret[ly]-tp_ret[ly-1])^(v-tp_ret[ly])) <= 0)
                tp_ret.pop_back();
            else
                break;
        tp_ret.push_back(v);
    }
    
    vector<pt> ret;
    for(int lx = 0;lx < bt_ret.size();lx++)
        ret.push_back(bt_ret[lx]);
    for(int lx = 0;lx < tp_ret.size();lx++)
        ret.push_back(tp_ret[lx]);
    return ret;
}

double CalArea(vector<pt> inp){
    double ret = 0;
    int len = inp.size();
    inp.push_back(inp[0]);
    for(int lx = 0;lx < len;lx++){
        ret += inp[lx]^inp[lx+1];
    }
    if(ret < 0) ret = -ret;
    return ret/2;
}

int main(){
    int T; scanf("%d", &T);
    while(T--){
        int n; scanf("%d", &n);
        vector<pt> get;
        double area1 = 0;
        for(int lx = 0;lx < n;lx++){
            double x, y, w, h, j;
            scanf("%lf %lf %lf %lf %lf", &x, &y, &w, &h, &j);
            area1 += w*h;
            double ang = -j*PI/180;
            get.push_back(pt(x, y) + pt(w/2, h/2).rotate(ang));
            get.push_back(pt(x, y) + pt(w/2, -h/2).rotate(ang));
            get.push_back(pt(x, y) + pt(-w/2, -h/2).rotate(ang));
            get.push_back(pt(x, y) + pt(-w/2, h/2).rotate(ang));
        }
        printf("%.1f %c\n",area1*100/CalArea(ConvexHull(get)), '%');
    }
    return 0;

}

2015年2月18日 星期三

UVA 12538 - Version Controlled IDE

是說從terminal 複製過會變這樣噢._.
筆記一下
code時大蓋遇到兩個問題

1.  string需要d&c的加進去,儘量平衡
2. 冊資有加密(強迫在線)



#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>

using namespace std;

int delta = 0;

int grand(){
    return rand()^0xdeadbeaf;
}

struct Jeap{
    Jeap* l;
    Jeap* r;
    int sz;
    char val;
    int pri;
    Jeap(char _v = 0){
        l = nullptr, r = nullptr;
        sz = 1;
        val = _v;
        pri = rand();
        return;
    }
    int Size(){
        if(this == nullptr) return 0;
        return sz;
    }
    void Update(){
        sz = l->Size() + r->Size() + 1;
        return;
    }
    void Print(){
        if(this == nullptr)
            return;
        l->Print();
        printf("%c", val);
        delta += (val == 'c');
        r->Print();
        return;
    }
};

Jeap* Cp(Jeap* a){
    if(a == nullptr)
        return nullptr;
    Jeap* ret = new Jeap();
    *ret = *a;
    return ret;
}

Jeap* Merge(Jeap* a, Jeap* b){
    if(a == nullptr) return Cp(b);
    if(b == nullptr) return Cp(a);
    if(a->pri > b->pri){
        a = Cp(a);
        a->r = Merge(a->r, b);
        a->Update();
        return a;
    }else{
        b = Cp(b);
        b->l = Merge(a, b->l);
        b->Update();
        return b;
    }
}

void Split(Jeap* org, int low, Jeap* &a, Jeap* &b){
    if(!low){
        a = nullptr, b = Cp(org);
    }else if(org == nullptr) a = nullptr, b = nullptr;
    else if(org->l->Size() >= low){
        b = Cp(org);
        Split(org->l, low, a, b->l);
        b->Update();
    }else{
        a = Cp(org);
        Split(org->r, low-org->l->Size()-1, a->r, b);
        a->Update();
    }
    return;
}

typedef Jeap* ptrJeap;

Jeap* jver[50005];
int ver;
void Init(){
    jver[0] = nullptr;
    ver = 0;
    return;
}

Jeap* Build(const char* str, int ll, int rr){
    if(ll > rr) return nullptr;
    int md = (ll+rr)>>1;
    Jeap* ret = nullptr;
    ret = Merge(ret, Build(str, ll, md-1));
    ret = Merge(ret, new Jeap(str[md]));
    ret = Merge(ret, Build(str, md+1, rr));
    return ret;
}

void PrintVer(int ts = ver){
    printf("ver%d -> [", ts);
    jver[ts]->Print();
    printf("]\n");
    return;
}

void Insert(int p, const char* str){
    ptrJeap a, b;
    Split(jver[ver], p, a, b);
    a = Merge(a, Build(str, 0, strlen(str)-1));
    jver[++ver] = Merge(a, b);
    return;
}

void Delete(int p, int c){
    ptrJeap a, b, b1, c1;
    Split(jver[ver], p, a, b);
    Split(b, c, b1, c1);
    jver[++ver] = Merge(a, c1);
    return;
}

void Iter(int _ver, int p, int c){
    ptrJeap a, b, b1, c1;
    Split(jver[_ver], p, a, b);
    Split(b, c, b1, c1);
    b1->Print();
    puts("");
    jver[_ver] = Merge(a, b1);
    jver[_ver] = Merge(jver[_ver], c1);
    return;
}

char s[200];
int main(){
    Init();
    delta = 0;
    int n; scanf("%d", &n);
    int op, v, p, c;
    while(n--){
        scanf("%d", &op);
        if(op == 1){
            scanf("%d %s", &p, s);
            Insert(p - delta, s);
        }else if(op == 2){
            scanf("%d %d", &p, &c);
            Delete(p-1 - delta, c - delta);
        }else if(op == 3){
            scanf("%d %d %d", &v, &p, &c);
            Iter(v - delta, p-1 - delta, c - delta);
        }
        //for(int lx = 0;lx <= ver;lx++)
        //    PrintVer(lx);
    }
    return 0;

}

2014年11月15日 星期六

UVa 12697 - Minimal Subarray Length

我,真是個笨蛋

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<utility>
#include<map>
#include<cmath>
#define INF 10000000
using namespace std;
typedef long long int int64;
int64 arr[500050];
int tree[2100000];
int base;
void init(int n){
    base = (1<<((int)(ceil(log2(n+3))))) - 1;
    for(int lx = 1;lx <= 2*base+1;lx++)
        tree[lx] = -1;
    return;
}
void modify(int pos, int val){
    pos += base+1;
    tree[pos] = val;
    for(pos>>=1;pos;pos>>=1)
        tree[pos] = max(tree[pos+pos], tree[pos+pos+1]);
    return;
}
int query(int a, int b){
    a++, b++;
    int ret = -1;
    for(a += base-1, b+= base+1; a^b^1;a>>=1, b>>=1){
        //printf("%d %d\n",a,b);
        if(~a&1) ret = max(ret, tree[a^1]);
        if(b&1) ret = max(ret, tree[b^1]);
    }
    return ret;
}
int main()
{
    int T;scanf("%d", &T);
    while(T--){
        int n; int64 k; scanf("%d %lld", &n, &k);
        map<int64, int> mm;
        arr[0] =  0;
        mm[0] = 0, mm[k] = 0;
        for(int lx = 0;lx < n;lx++){
            int64 inp; scanf("%lld", &inp);
            arr[lx+1] = arr[lx]+inp;
            mm[arr[lx+1]] = 0;
            mm[arr[lx+1]+k] = 0;
        }
        int cc = 0;
        init(mm.size()+1);
        for(map<int64, int>::iterator it = mm.begin(); it != mm.end(); it++)
            it->second = cc++;
        int len = INF;
        for(int lx = 0;lx <= n;lx++){
            int ans = query(0, mm[arr[lx]]);
            //printf("q at %d\n", mm[arr[lx]]);
            if(ans != -1)
                len = min(len, lx-ans);
            //printf("mod at %d\n", mm[arr[lx]+k]);
            modify(mm[arr[lx]+k],lx);
        }
        printf("%d\n", (len == INF) ? -1:len);
    }
    return 0;
}

2014年10月31日 星期五

UVAOJ 1515 Pool construction

給每個格子一個點
連到s代表選地,連到t代表選洞
相鄰的再連一條cost為b的無向邊
做最大流

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<utility>
#include<map>
#include<set>
#include<queue>
#include<cmath>
#define INF 10000000
using namespace std;
typedef long long int int64;
struct{ int a, b, val; }lks[100000]; int lks_cnt;
vector<int> to[100000];
int _n;
void init(int n){
 _n = n;
 for(int lx = 0;lx < n;lx++){
  to[lx].clear();
 }
 lks_cnt = 0;
 return;
}
void addlink(int a, int b, int ab){
 //printf("link %d -> %d with %d\n", a, b, ab);
 lks[lks_cnt].a = a, lks[lks_cnt].b = b, lks[lks_cnt].val = ab; to[a].push_back(lks_cnt++);
 lks[lks_cnt].a = b, lks[lks_cnt].b = a, lks[lks_cnt].val = 0; to[b].push_back(lks_cnt++);
 return;
}
int dis[100000], que[100000] ;
int bfs(int s, int t){
 int n = _n;
 for(int lx = 0;lx < n;lx++){
  dis[lx] = -1;
 }
 dis[s] = 0;
 int qs = 0, qe = 1;
 que[0] = s;
 while(qs < qe){
  int g = que[qs++];
  for(int lx = 0;lx < to[g].size();lx++){
   int lind = to[g][lx];
   int pind = lks[lind].b;
   if(dis[pind] != -1) continue;
   if(lks[lind].val == 0) continue;
   dis[pind] = dis[g]+1;
   que[qe++] = pind;
  }
 }
 return (dis[t] != -1);
}
bool vis[100000];
int dfs(int vv, int df, int s, int t){
 //printf("dfs: %d\n", vv);
 //for(int lx = 0;lx/100000 < 100;lx++);
 if(vv == t) return df;
 if(vis[vv]) return 0;
 vis[vv] = true;
 for(int lx = 0;lx < to[vv].size();lx++){
  int lind = to[vv][lx];
  int pind = lks[lind].b;
  if(lks[lind].val == 0) continue;
  if(dis[pind] != dis[vv] +1) continue;
  int f = dfs(pind, min(df, lks[lind].val), s, t);
  if(f > 0){
   lks[lind].val -= f;
   lks[lind^1].val += f;
   return f;
  }
 }
 return 0;
}
int dinic(int s, int t){
 int f = 0, df = 0;
 while(bfs(s, t))
  for(;;){
   memset(vis, 0, sizeof(vis));
   int df = dfs(s, 1000000000, s, t);
   if(df == 0) break;
   f += df;
  }
 return f;
}
int ctr = 0; int get_ind(){return ctr++;}
int main()
{
 int T;scanf("%d", &T);
 while(T--){
  int w, h; scanf("%d %d", &w, &h);
  int d, f, b;scanf("%d %d %d", &d, &f, &b);
  int Map[60][60];
  for(int lx = 0;lx < h;lx++){
   char str[1000];
   scanf("%s", str);
   for(int ly = 0;ly < w;ly++)
    Map[lx][ly] = str[ly] == '#';
  }

  ctr = 0;
  int ss = get_ind(), tt = get_ind();
  int map_nod[100][100];
  for(int lx = 0;lx < h;lx++)
   for(int ly = 0;ly < w;ly++)
    map_nod[lx][ly] = get_ind();
  int ind_count = get_ind();
  init(ind_count);
  for(int lx = 0;lx < h;lx++){
   for(int ly = 0;ly < w;ly++) {
    if((lx == 0) or (lx == h-1) or (ly == 0) or (ly == w-1)){
     if(Map[lx][ly]){
      addlink(map_nod[lx][ly], tt, INF);
     }else{
      addlink(ss, map_nod[lx][ly], f);
      addlink(map_nod[lx][ly], tt, INF);
     }
    }else{
     if(Map[lx][ly]){
      addlink(map_nod[lx][ly], tt, d);
     }else{
      addlink(ss, map_nod[lx][ly], f);
     }
    }
   }
  }
  for(int lx = 0;lx < h-1;lx++){
   for(int ly = 0;ly < w;ly++){
    //down
    addlink(map_nod[lx][ly], map_nod[lx+1][ly], b);
    addlink(map_nod[lx+1][ly], map_nod[lx][ly], b);
   }
  }
  for(int lx = 0;lx < h;lx++){
   for(int ly = 0;ly < w-1;ly++){
    //down
    addlink(map_nod[lx][ly], map_nod[lx][ly+1], b);
    addlink(map_nod[lx][ly+1], map_nod[lx][ly], b);
   }
  }
  printf("%d\n", dinic(ss, tt));
 }
 return 0;
}