#
為樹狀樹組量身打造的題...
不過我是線段樹..
#include <iostream>
#include <stdio.h>
using namespace std;
const int MAXN=32005;
struct node


{
int l,r;
int d;
};
node t[MAXN*4];
int ans[MAXN];
void build(int l_,int r_,int p)


{
t[p].l=l_;
t[p].r=r_;
t[p].d=0;
if (l_!=r_)

{
build(l_,(l_+r_)/2,p<<1);
build((l_+r_)/2+1,r_,(p<<1)+1);
}
}

int find(int r_,int p)


{
if (t[p].r<=r_) return t[p].d;
int l=t[p].l;
int r=t[p].r;
int sum=0;
if (r_<=(l+r)/2) sum+=find(r_,p*2);
else sum+=t[p*2].d+find(r_,p*2+1);
return sum;
}
void insert(int x,int p)


{
int l=t[p].l;
int r=t[p].r;
t[p].d++;
if (l==r) return;
if (x<=(l+r)/2) insert(x,p*2); else insert(x,p*2+1);
}
int n;
int main()


{
memset(ans,0,sizeof(ans));
build(0,MAXN,1);
cin>>n;
for (int i=1;i<=n;i++)

{
int x,y;
scanf("%d %d",&x,&y);
ans[find(x,1)]++;
insert(x,1);
}
for (int i=0;i<n;i++)
cout<<ans[i]<<endl;
// system("pause");
return 0;
}

摘要: 裸treap...學會了刪除..orz..
#include <iostream>//#include <fstream>using namespace std;//ifstream fin("t3481.in");const int MAXN=100000;const int IN...
閱讀全文
摘要: treap..有幾個地方寫的很尷尬...其實我沒寫過平衡樹...任何的平衡樹..所以我就把對于size的維護寫錯了..orz..然后我又把砍掉一棵子樹那部分寫錯了..我感覺這樣砍樹是會造成一定的不平衡的..但不平衡會很小.呃..其實也不能這么說..應該說..會造成不平衡..但這個不平衡帶給我的負擔不會高于我曾經的負擔..orz..貌似是這樣
#include <iostream&...
閱讀全文
2分圖
構圖
兩個集合是一樣的,都是所有的*號
如果某兩個*之間挨著,就連線
求最大匹配
可以輕易得出這個最大匹配把每個*都求了2遍
因此除以2,再加上未匹配的*,得解..
難點就是構圖..
事實上匹配,網絡流等的難點也就是構圖
#include <iostream>
//#include <fstream>
using namespace std;
//ifstream fin("t3020.in");
struct node


{
int x,y;
};
const int MAXN=401;
node edge[MAXN];
bool connect[MAXN][MAXN];
bool hash[MAXN];
int v[MAXN];
int n;
int h,w;
int len;

bool find(int x)


{
for (int i=1;i<=len;i++)

{
if (!connect[x][i]) continue;
if (!hash[i])

{
hash[i]=true;
if (v[i]==0||find(v[i]))

{
v[i]=x;
return true;
}
}
}
return false;
}
int main()


{
cin>>n;
while(n--)

{
cin>>h>>w;
len=0;
for (int i=1;i<=h;i++)
for (int j=1;j<=w;j++)

{
char ch;
cin>>ch;
if ('*'==ch)

{
len++;
edge[len].x=i;
edge[len].y=j;
}
}
//init
memset(connect,0,sizeof(connect));
for (int i=1;i<=len;i++)
for (int j=1;j<=len;j++)

{
if (i==j) continue;
if (1==abs(edge[i].x-edge[j].x)+abs(edge[i].y-edge[j].y))
connect[i][j]=true;
}
//
memset(v,0,sizeof(v));
int answer=0,ans=0;
for (int i=1;i<=len;i++)

{
memset(hash,0,sizeof(hash));
if (find(i)) answer++;
else
ans++;
}
cout<<answer/2+ans<<endl;
// system("pause");
}
return 0;
}
