A - Binary Tree Traversals
记一个模板
#include<iostream>
using namespace std;
typedef struct Tree{
Tree *left;
Tree *right;
int value;
}Tree;
Tree *root;
Tree* create(int *preorder,int *inorder,int n)
{
Tree *temp;
for(int i=0;i<n;i++)
{
if(preorder[0]==inorder[i])
{
temp=(Tree*)malloc(sizeof(Tree));
temp->value=inorder[i];
temp->left=create(preorder+1,inorder,i);
temp->right=create(preorder+i+1,inorder+i+1,n-i-1);
return temp;
}
}
return NULL;
}
void postOrder(Tree *postTree)
{
if(postTree!=NULL)
{
postOrder(postTree->left);
postOrder(postTree->right);
if(postTree==root)
printf("%d
",postTree->value);
else
printf("%d ",postTree->value);
}
}
int main()
{
int n;
int preorder[2010],inorder[2010];
while(scanf("%d",&n)!=EOF)
{
root=NULL;
for(int i=0;i<n;i++)
scanf("%d",&preorder[i]);
for(int i=0;i<n;i++)
scanf("%d",&inorder[i]);
root=create(preorder,inorder,n);
postOrder(root);
}
return 0;
}
B - The order of a Tree
bst树的创建,虽然不知道它有什么用。。。
创建的时候每一次都是从根【总根】开始判断
#include<iostream>
#include<set>
#define N 100001
using namespace std;
set<int>order;
int k,ii;
int n;
struct node
{
node* l;
node* r;
int date;
node(int date,node *l=NULL,node *r=NULL):date(date),l(l),r(r){}
};
void create(node* &root,int val)
{
if(!root)
{
root =new node(val);
}
else if(val<root->date)
{
create(root->l,val);
}
else
{
create(root->r,val);
}
}
void preorder(node *root)
{
if(root)
{
printf("%d%c",root->date,ii==n-1 ? '
':' ');
++ii;
preorder(root->l);
preorder(root->r);
}
}
int main()
{
node *root;
root=NULL;
cin>>n;
int temp;
for(int i=0;i<n;++i)
{
scanf("%d",&temp);
create(root,temp);
}
preorder(root);
return 0;
}
C - 二叉搜索树
#include<iostream>
#include<cstring>
using namespace std;
#define MAX 200
char tree1[MAX],tree2[MAX],n;
string s;
void create_tree(char tree[],char node)
{
int root=1;
while(tree[root]!=' ')
{
if(node < tree[root]) { root*=2; }
else { root*=2; root++; }
}
tree[root] = node;
}
int main()
{
while(scanf("%d",&n)&&n)
{
cin>>s;
memset(tree1,0,sizeof(tree1));
for(int i=0;i<s.length();++i)create_tree(tree1,s[i]);
for(int i=0;i<n;++i)
{
cin>>s;
memset(tree2,0,sizeof(tree2));
for(int i=0;i<s.length();++i) create_tree(tree2,s[i]);
if(memcmp(tree1,tree2,sizeof(tree1))==0) cout<<"YES
";
else cout<<"NO
";
}
}
return 0;
}
D - Hardwood Species
#include<iostream>
#include<cstring>
#include<map>
#include<stdio.h>
using namespace std;
#define MAX 200
string s;
int main()
{
map<string,int>mp;
int num=0;
while(getline(cin,s)!=NULL){ mp[s]++;num++; }
map<string,int>::iterator i;
for(i=mp.begin();i!=mp.end();++i)
{
cout<<i->first;printf(" %.4f
",i->second*100.0/num);
}
return 0;
}
E - Lost Cows
#include<iostream>
#include<cstdio>
/**
二叉查找树:(又:二叉搜索树,二叉排序树)
它或者是一棵空树,或者是二叉树:
若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
线段树:
是一种二叉搜索树,与区间树相似,
它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点
分析: 剩下的数中
有n个数比他小,那么这个数的值是【拿去后的数中】n+1
*/
using namespace std;
const int maxn=10000;
int small[maxn],ans[maxn];
struct node{
int lc,rc,len;
};
node tree[maxn*3];//这里一开始数组开小了出现了rte
void build(int x,int lc,int rc)//构造一棵线段树
{
tree[x].lc=lc,tree[x].rc=rc;//记录区间的端点值
tree[x].len=rc-lc+1;//记录区间长
if(lc==rc)return ;
build(x*2,lc,(lc+rc)/2);//构造左子树
build(x*2+1,(lc+rc)/2+1,rc);//构造右子树
}
int query(int base,int k)
{
tree[base].len--;//代表有数被拿走,这个区间的长度自减
if(tree[base].lc==tree[base].rc)return tree[base].lc;//当左右子树的端点值一样的时候戴白哦达到了叶子
if(k<=tree[base*2].len)// 区间的长度代表了数的个数
{
return query(base*2,k);//左边
}
else
{
return query(base*2+1,k-tree[base*2].len);//右边
}
}
int main(void)
{
int n;
scanf("%d",&n);
small[1]=0;
for(int i=2;i<=n;i++)//输入数据
{
scanf("%d",&small[i]);
}
build(1,1,n);//建线段树 1-n从小到大
for(int i=n;i>=1;i--)//从后往前找
{
ans[i]=query(1,small[i]+1);//从根开始,找区间长度为的small[i]+1
}
for(int i=1;i<=n;i++)
{
printf("%d
",ans[i]);
}
return 0;
}
F - Mayor's posters
POJ - 2528[lazy]
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#define md(l,r) (l+r)>>1
#define rson(x) x<<1|1
#define lson(x) x<<1
#define endl '
'
#define sc(x) scanf("%d",&x)
using namespace std;
typedef long long LL;
const int inf=0x3f3f3f3f;
const int size=1e5+5;
int Ledge[size],Redge[size];//放端点的
int lid[size],rid[size];
vector<int > V;
typedef long long LL;
struct node
{
int l,r;
LL sum;
LL tag;
} tree[size<<2];
void build(int k,int l,int r)
{
tree[k].l=l,tree[k].r=r;
if(l==r)
{
tree[k].sum=0;
return ;
}
int mid(md(l,r));
build(lson(k),l,mid);
build(rson(k),mid+1,r);
}
void change(int k)
{
if(tree[k].l!=tree[k].r)
{
int ls=lson(k),rs=rson(k);
tree[ls].sum=tree[k].tag;
tree[rs].sum=tree[k].tag;
tree[ls].tag=tree[k].tag;
tree[rs].tag=tree[k].tag;
}
tree[k].tag=0;
}
void Print()
{
for(int i=0;i<20;++i)
{
cout<<i<<":"<<tree[i].l<<","<<tree[i].r<<","<<tree[i].sum<<","<<tree[i].tag<<endl;
}
}
int query(int k,int l,int r)
{
LL ans=inf;
if(tree[k].tag) change(k);//如果已经被染过色了,端点染色然后初始化
if(tree[k].l==l&&tree[k].r==r)
{
return tree[k].sum;
}
int mid=md(tree[k].l,tree[k].r);
if(r<=mid) ans=query(lson(k),l,r);//小区间在左边
else if(l>=mid+1) ans=query(rson(k),l,r);//小区间在右边
else ans=min(query(lson(k),l,mid),query(rson(k),mid+1,r));//mid在小区间内就把小区间分割
return ans;
}
void add(int k,int l,int r,LL x)
{
if(tree[k].tag) change(k);//端点染色判断
if(tree[k].l==l&&tree[k].r==r)
{
tree[k].sum=x;//区间内部涂色
tree[k].tag=x;//tag用来记录这个区间属于哪个小区间
return ;
}
int mid=md(tree[k].l,tree[k].r);
if(l>=mid+1) add(rson(k),l,r,x);
else if(r<=mid) add(lson(k),l,r,x);
else add(lson(k),l,mid,x),add(rson(k),mid+1,r,x);
tree[k].sum=min(tree[lson(k)].sum,tree[rson(k)].sum);//从左右端点选着那个小的作为这个区间的颜色
}
int main()
{
int t;sc(t);
int ans=0;
while(t--)
{
int n;
ans=0;
V.clear();
memset(tree,0,sizeof(tree));
sc(n);
for(int i=0; i<n; i++)
{
sc(Ledge[i]),sc(Redge[i]);//输入左右端点
V.push_back(Ledge[i]),V.push_back(Redge[i]);
}
sort(V.begin(),V.end());//建立数组
V.erase(unique(V.begin(),V.end()),V.end());//离散化——建新的数组
/*
iterator erase( iterator _First, iterator _Last);
删除从_First开始到_Last位置(不包括_Last位置)的元素
返回值也是一个迭代器,指向最后一个删除元素的下一个位置。
unique函数的功能:”删除”序列中所有相邻的重复元素(只保留一个)。
此处的删除,并不是真的删除,而是指重复元素的位置被不重复的元素给占领了
*/
for(int i=0; i<n; i++) lid[i]=lower_bound(V.begin(),V.end(),Ledge[i])-V.begin()+1; //离散化——绑定新的区间
for(int i=0; i<n; i++) rid[i]=lower_bound(V.begin(),V.end(),Redge[i])-V.begin()+1;
/*
lower_bound():int t=lower_bound(a+l,a+r,m)-a
在升序排列的a数组内二分查找[l,r)区间内的值为m的元素。
返回m在数组中的下标
*/
build(1,1,V.size()+1);//建线段树
for(int i=n-1; i>=0; i--) //倒着来
{
if(query(1,lid[i],rid[i])==0) //传入一个区间和根
{
add(1,lid[i],rid[i],i);
ans++;
}
}
cout<<ans<<endl;
}
return 0;
}
G - A Simple Problem with Integers
POJ - 3468 [lazy]
#include<iostream>
#include<stdio.h>
using namespace std;
typedef long long ll ;
const int N=1e5+10;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
struct Node
{
int l,r;
int mid()
{ return (l+r)>>1; }
}tree[N<<2];
ll sum[N<<2],add[N<<2];
void PushUp(int rt)
{
sum[rt] = sum[rt<<1]+sum[rt<<1|1];
}
void PushDown(int rt,int m)
{
if(add[rt])
{
add[rt<<1]+=add[rt];//左右节点添加延迟修改量,有可能有多个延迟修改量,这里用+=
add[rt<<1|1]+=add[rt];
sum[rt<<1]+=add[rt]*(m-(m>>1));
sum[rt<<1|1]+=add[rt]*(m>>1);
add[rt]=0;
}
}
void build(int l,int r,int rt)
{
tree[rt].l=l;
tree[rt].r=r;
add[rt]=0;
if(l==r)
{
scanf("%I64d",&sum[rt]);return;
}
int m=tree[rt].mid();
build(lson) ;
build(rson) ;
PushUp(rt);
}
void update(int c,int l,int r,int rt)
{
if(tree[rt].l==l&&tree[rt].r==r)
{
add[rt]+=c;//给父节点打上一个lazy标签,子节点看情况修改
sum[rt]+=(ll)c*(r-l+1);
return;
}
if(tree[rt].l==tree[rt].r) return;
PushDown( rt , tree[rt].r - tree[rt].l + 1);
int m=tree[rt].mid();
if(r<=m) update(c,l,r,rt<<1);
else if(l>m) update(c,l,r,rt<<1|1);
else
{
update(c,lson);
update(c,rson);
}
PushUp(rt);
}
ll query(int l,int r,int rt)
{
if(l==tree[rt].l&&r==tree[rt].r) return sum[rt];
PushDown(rt,tree[rt].r-tree[rt].l+1);//一层
int m=tree[rt].mid();
ll res = 0;
if(r<=m) res+=query(l,r,rt<<1);
else if(l>m) res+=query(l,r,rt<<1|1);
else
{
res+=query(lson);
res+=query(rson);
}
return res;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
build(1,n,1);
while(m--)
{
char ch[2];
scanf("%s",ch);
int a,b,c;
if(ch[0]=='Q')
{
scanf("%d%d",&a,&b);
printf("%lld
",query(a,b,1));
}
else
{
scanf("%d%d%d",&a,&b,&c);
update(c,a,b,1);
}
}
}
return 0;
}
H - 敌兵布阵
#include<iostream>
#include<cstring>
#include<stdio.h>
using namespace std;
typedef long long ll ;
const int N=1e5+10;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
struct Node
{
int l,r;
int mid()
{ return (l+r)>>1; }
}tree[N<<2];
ll sum[N<<2],add[N<<2];
void PushUp(int rt)
{
sum[rt] = sum[rt<<1]+sum[rt<<1|1];
}
void Init()
{
memset(sum,0,sizeof(N<<2));
memset(add,0,sizeof(N<<2));
memset(tree,0,sizeof(N<<2));
}
void build(int l,int r,int rt)
{
tree[rt].l=l;tree[rt].r=r;
if(l==r)
{
scanf("%I64d",&sum[rt]);return;
}
int m=tree[rt].mid();
build(lson) ; build(rson) ;
PushUp(rt);
}
void update(int c,int l,int r,int rt)
{
if(tree[rt].r==tree[rt].l)
{
sum[rt]+=c;
return;
}
int m=tree[rt].mid();
if(r<=m) update(c,l,r,rt<<1);
else if(l>m) update(c,l,r,rt<<1|1);
else
{
update(c,lson);
update(c,rson);
}
PushUp(rt);
}
ll query(int l,int r,int rt)
{
if(l==tree[rt].l&&r==tree[rt].r) return sum[rt];
int m=tree[rt].mid();ll res = 0;
if(r<=m) res+=query(l,r,rt<<1);
else if(l>m) res+=query(l,r,rt<<1|1);
else
{
res+=query(lson);
res+=query(rson);
}
return res;
}
int main()
{
int T,N;scanf("%d",&T);
for(int i=1;i<=T;++i)
{
scanf("%d",&N);build(1,N,1);
string ch;
int a,b,c;
printf("Case %d:
",i);
do
{
cin>>ch;
if(ch=="Query")
{
scanf("%d%d",&a,&b);
printf("%lld
",query(a,b,1));
}
else if(ch=="Add")
{
scanf("%d%d",&a,&b);
update(b,a,a,1);
}
else if(ch=="Sub")
{
scanf("%d%d",&a,&b);
update(-b,a,a,1);
}
}while(ch!="End");
Init();
}
return 0;
}
I - Minimum Inversion Number
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 5555
#define inf 99999999
int a[maxn];
struct node{
int l,r,sum;//sum记录区间长
}tree[maxn*4];
int ans=0;
void pushup(int v)
{
tree[v].sum=tree[v<<1].sum+tree[v<<1|1].sum;
}
void build(int l,int r,int v)
{
tree[v].l=l;tree[v].r=r;tree[v].sum=0;
if(l==r) return;
int mid=(l+r)/2;
build(l,mid,v<<1);
build(mid+1,r,v<<1|1);
}
int query(int l,int r,int v)//求区间长度
{
if(l==tree[v].l&&r==tree[v].r) return tree[v].sum;
int mid=(tree[v].l+tree[v].r)/2;
if(r<=mid) return query(l,r,v<<1);
else if(l>mid) return query(l,r,v<<1|1);
else
{
return query(l,mid,v<<1)+query(mid+1,r,v<<1|1);
}
}
void update(int pos,int v)//更新区间长度
{
if(tree[v].l==tree[v].r){ tree[v].sum=1;return ; }
int mid=(tree[v].l+tree[v].r)/2;
if(pos<=mid) update(pos,v<<1);
else update(pos,v<<1|1);
pushup(v);
}
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(a,0,sizeof(a));
for(int i=0;i<n;i++) scanf("%d",&a[i]);
build(0,n-1,1);
int sum=0,min1=inf;
for(int i=0;i<n;i++)
{
ans=query(a[i],n-1,1);//计算a[i]对应的逆序数个数 =大于它的且已经出现过的数的个数
sum+=ans;
update(a[i],1);//将a[i]标记到数列中
}
for(int i=0;i<n;i++)
{
sum+=n-(a[i]+1)-a[i];
if(sum<min1) min1=sum;
}
printf("%d
",min1);
}
}
J - Just a Hook