牛客题 - 统计颜色
1.题意:
2.题解:
3.ac代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
ll a[N];
struct Node{
ll l,r;
ll sum,add;
}tr[N<<2];
void pushdown(ll u){
if(tr[u].add){
tr[u<<1].sum|=tr[u].add;
tr[u<<1|1].sum|=tr[u].add;
tr[u<<1].add|=tr[u].add;
tr[u<<1|1].add|=tr[u].add;
tr[u].add=0;
}
}
void pushup(Node &u,Node &l,Node &r){
u.sum=l.sum|r.sum;
}
void pushup(ll u){
pushup(tr[u],tr[u<<1],tr[u<<1|1]);
}
void build(ll u,ll l,ll r){
if(l==r){
tr[u]={l,r};
}else{
tr[u]={l,r};
int mid=(l+r)>>1;
build(u<<1,l,mid);build(u<<1|1,mid+1,r);
pushup(u);
}
}
void change(ll u,ll l,ll r,ll x){
if(l<=tr[u].l&&tr[u].r<=r){
tr[u].sum|=x;
tr[u].add|=x;
return;
}else{
//cout<<"u:"<<u<<"--l:"<<tr[u].l<<"--r:"<<tr[u].r<<"--sum:"<<tr[u].sum<<endl;
ll mid=(tr[u].l+tr[u].r)>>1;
pushdown(u);
if(l<=mid) change(u<<1,l,r,x);
if(r>mid) change(u<<1|1,l,r,x);
pushup(u);
}
}
Node query(ll u,ll l,ll r){
if(l<=tr[u].l&&tr[u].r<=r){
return tr[u];
}
ll mid=(tr[u].l+tr[u].r)>>1;
pushdown(u);
if(r<=mid) return query(u<<1,l,r);
if(l>=mid) return query(u<<1|1,l,r);
else{
Node node;
auto lson=query(u<<1,l,r);
auto rson=query(u<<1|1,l,r);
pushup(node,lson,rson);
return node;
}
}
int main(){
ll n,m;
while(cin>>n>>m){
build(1,1,n);
int op,l,r;
ll x;
for(int i=1;i<=m;i++){
cin>>op>>l>>r;
if(op==1){
cin>>x;
change(1,l,r,(ll)1<<x);
}else{
auto node=query(1,l,r);
ll sum=node.sum;
ll ans=0;
while(sum){
if(sum&1) ans++;
sum>>=1;
}
cout<<ans<<endl;
}
}
}
}
HDU - Cow Sorting (树状数组)
1.题意:
2.题解:
3.ac代码:
#include<bits/stdc++.h>
#include<string>
using namespace std;
const int N=1e5+10;
typedef long long ll;
const int big=1e5;
ll tr[N];
ll cnt[N];
ll a[N];
int n,m;
int tot;
//map<ll,int> m;
int lowbit(int x){
return x&(-x);
}
void add1(int l,int x){
for(int i=l;i<=big;i+=lowbit(i)){
tr[i]+=x;
}
}
void add2(int l,int x){
for(int i=l;i<=big;i+=lowbit(i)){
cnt[i]+=x;
}
}
ll sum1(int l){
ll res=0;
for(int i=l;i;i-=lowbit(i)){
res+=tr[i];
}
return res;
}
ll sum2(int l){
ll res=0;
for(int i=l;i;i-=lowbit(i)){
res+=cnt[i];
}
return res;
}
int main(){
int t;
while(cin>>n){
ll res=0;
ll a;
memset(cnt,0,sizeof cnt);
memset(tr,0,sizeof tr);
for(int i=1;i<=n;i++){
cin>>a;
ll ans1=sum1(big)-sum1(a);
ll ans2=sum2(big)-sum2(a);
res+=ans1+ans2*a;
add2(a,1);
add1(a,a);
}
cout<<res<<endl;
}
}
HDU-Turing Tree
1.题意:
2.题解:
3.ac代码:
#include<bits/stdc++.h>
#include<string>
using namespace std;
const int N=1e5+10;
typedef long long ll;
const int big=1e5;
ll a[N];
map<ll,ll> mp;
ll sq;
struct Q{
ll l,r,id;
bool operator<(const Q &w)const{
if(l/sq!=w.l/sq) return l<w.l;
if(l/sq&1) return r<w.r;
return r>w.r;
}
}q[N];
ll n;
ll ans[N];
ll b[N];
ll res;
ll cnt[N];
void del(int l){
if(cnt[b[l]]==1){
res-=a[l];
}
cnt[b[l]]--;//!!!!万万没想到,die在这,de了一天,竟然错在这,,,!!!我一开始判断>0时才能减
}
void add(int l){
if(cnt[b[l]]==0){
// cout<<"--b[a[l]:"<<b[a[l]]<<endl;
res+=a[l];
}
cnt[b[l]]++;
}
int main(){
int t;
ll x;
cin>>t;
while(t--){
mp.clear();
cin>>n;
res=0;
memset(ans,0,sizeof ans);
memset(q,0,sizeof q);
memset(a,0,sizeof a);
memset(b,0,sizeof b);
memset(cnt,0,sizeof cnt);
ll tot=0;
sq=sqrt(n);
for(int i=1;i<=n;i++){
cin>>a[i];
if(mp.count(a[i])==0) mp[a[i]]=++tot;
b[i]=mp[a[i]];
}
int m;
cin>>m;
//int l,r;
for(int i=1;i<=m;i++){
cin>>q[i].l>>q[i].r;
q[i].id=i;
}
sort(q+1,q+1+m);
ll l=1,r=0;
for(int i=1;i<=m;i++){
while(l<q[i].l){
del(l++);
}
while(l>q[i].l){
add(--l);
}
while(r<q[i].r){
add(++r);
}
while(r>q[i].r){
del(r--);
}
ans[q[i].id]=res;
}
for(int i=1;i<=m;i++){
cout<<ans[i]<<endl;
}
}
}
求和(DFS序+线段树/树状数组)
1.题意:
2.题解:
3.ac代码:
线段树
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
int tim=0;
int h[N],e[N<<1],ne[N<<1],idx;
int w[N];
int st[N],ed[N];
int id[N];
void add(int a,int b){
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u,int f){
st[u]=++tim;
id[tim]=u;
for(int i=h[u];i!=-1;i=ne[i]){
int j=e[i];
if(j==f) continue;
dfs(j,u);
}
ed[u]=tim;
}
struct Node{
int l,r,val,mark;
}tr[N<<2];
// void pushdown(int u){
// if(tr[u].mark){
// int t=tr[u].mark;
// tr[u<<1].val+=t;
// tr[u<<1|1].val+=t;
// tr[u<<1].mark=t;
// tr[u<<1|1].mark=t;
// tr[u].mark=0;
// }
// }
void pushup(Node &u,Node &l,Node &r){
u.val=l.val+r.val;
}
void pushup(int u){
pushup(tr[u],tr[u<<1],tr[u<<1|1]);
}
void build(int u,int l,int r){
if(l==r){
tr[u]={l,r,w[id[l]]};
return ;
}
// printf("%d,%d,%d\n",u,l,r);
int mid=l+r>>1;
tr[u].l=l;tr[u].r=r;
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
pushup(u);
}
void change(int u,int idx,ll x){
if(tr[u].l==idx&&tr[u].r==idx){
tr[u].val+=x;
}else{
int mid=tr[u].l+tr[u].r>>1;
// pushdown(u);
if(idx<=mid) change(u<<1,idx,x);
else change(u<<1|1,idx,x);
pushup(u);
}
}
int query(int u,int l,int r){
if(l>r) return 0;
if(l<=tr[u].l&&tr[u].r<=r){
return tr[u].val;
}
int mid=tr[u].l+tr[u].r>>1;
// pushdown(u);
int res=0;
if(l<=mid) res=query(u<<1,l,r);
if(r>mid) res+=query(u<<1|1,l,r);
return res;
}
int main(){
int n,m,k;
cin>>n>>m>>k;
memset(h,-1,sizeof h);
memset(ne,-1,sizeof ne);
for(int i=1;i<=n;i++){
scanf("%d",&w[i]);
}
for(int i=1;i<=n-1;i++){
int a,b;
scanf("%d%d",&a,&b);
// cout<<"a:"<<a<<" b:"<<b<<endl;
add(a,b),add(b,a);
}
int op,a,x;
dfs(k,0);
build(1,1,n);
for(int i=1;i<=m;i++){
scanf("%d%d",&op,&a);
if(op==1){
scanf("%d",&x);
change(1,st[a],x);
}else{
int l=st[a],r=ed[a];
int res=query(1,l,r);
printf("%d\n",res);
}
}
}
树状数组:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
int tim=0;
int h[N],e[N<<1],ne[N<<1],idx;
int w[N];
int st[N],ed[N];
int id[N];
int n;
void add(int a,int b){
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u,int f){
st[u]=++tim;
id[tim]=u;
for(int i=h[u];i!=-1;i=ne[i]){
int j=e[i];
if(j==f) continue;
dfs(j,u);
}
ed[u]=tim;
}
int tr[N];
int lowbit(int x){
return x&(-x);
}
void add1(int l,int x){
for(int i=l;i<=n;i+=lowbit(i)){
tr[i]+=x;
}
}
int sum(int l){
int res=0;
for(int i=l;i;i-=lowbit(i)){
res+=tr[i];
}
return res;
}
int main(){
int m,k;
scanf("%d%d%d",&n,&m,&k);
memset(ne,-1,sizeof ne);
memset(h,-1,sizeof h);
for(int i=1;i<=n;i++) cin>>w[i];
for(int i=1;i<=n-1;i++){
int a,b;
scanf("%d%d",&a,&b);
add(a,b);add(b,a);
}
dfs(k,0);
int op,a,x;
for(int i=1;i<=n;i++){
add1(st[i],w[i]);
}
for(int i=1;i<=m;i++){
scanf("%d%d",&op,&a);
if(op==1){
scanf("%d",&x);
add1(st[a],x);
}else{
int res=sum(ed[a])-sum(st[a]-1);
printf("%d\n",res);
}
}
}
HDU-Assign the task(DFS序+线段树)
1.题意:
2.题解:
3.ac代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e4+10;
int tim=0;
int h[N],e[N<<1],ne[N<<1],idx;
ll w[N];
int st[N],ed[N];
int id[N];
int n;
int du[N];
void add(int a,int b){
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u,int f){
st[u]=++tim;
id[tim]=u;
for(int i=h[u];i!=-1;i=ne[i]){
int j=e[i];
if(j==f) continue;
dfs(j,u);
}
ed[u]=tim;
}
struct Node{
int l,r;
ll val,mark;
}tr[N<<2];
void pushdown(int u){
if(tr[u].mark!=-1){
int t=tr[u].mark;
tr[u<<1].val=t;
tr[u<<1|1].val=t;
tr[u<<1].mark=t;
tr[u<<1|1].mark=t;
tr[u].mark=-1;
}
}
void pushup(Node &u,Node &l,Node &r){
u.val=l.val+r.val;
}
void pushup(int u){
pushup(tr[u],tr[u<<1],tr[u<<1|1]);
}
void build(int u,int l,int r){
if(l==r){
tr[u]={l,r,-1,-1};
return ;
}
// printf("%d,%d,%d\n",u,l,r);
int mid=l+r>>1;
tr[u].l=l;tr[u].r=r;
tr[u].val=tr[u].mark=-1;
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
tr[u<<1].val=tr[u<<1|1].val=tr[u<<1].mark=tr[u<<1|1].mark=-1;
//pushup(u);
}
void change(int u,int l,int r,ll x){
if(l<=tr[u].l&&tr[u].r<=r){
tr[u].val=x;
tr[u].mark=x;
return ;
}
int mid=(tr[u].l+tr[u].r)>>1;
pushdown(u);
if(l<=mid) change(u<<1,l,r,x);
if(r>mid) change(u<<1|1,l,r,x);
}
int query(int u,int idx){
//cout<<"u: "<<u<<" l r:"<<l<<" "<<r<<" var:"<<tr[u].val<<" "
if(idx==tr[u].l&&tr[u].r==idx){
return tr[u].val;
}
int mid=(tr[u].l+tr[u].r)>>1;
pushdown(u);
if(idx<=mid) return query(u<<1,idx);
if(idx>mid) return query(u<<1|1,idx);
}
int main(){
int t,q;
cin>>t;
for(int tt=1;tt<=t;tt++){
printf("Case #%d:\n",tt);
cin>>n;
idx=0;tim=0;
memset(tr,0,sizeof tr);
memset(h,-1,sizeof h);
memset(ne,-1,sizeof ne);
memset(st,0,sizeof st);
memset(ed,0,sizeof ed);
memset(e,0,sizeof e);
memset(du,0,sizeof du);
//memset(w,-1,sizeof w);
int u,v;
for(int i=1;i<=n-1;i++){
cin>>u>>v;
add(u,v);add(v,u);
du[u]++;
}
int k;
for(k=1;k<=n;k++){
if(du[k]==0) dfs(k,0);
}
build(1,1,n);
cin>>q;
char op[2];
int x,y;
int res;
for(int i=1;i<=q;i++){
cin>>op>>x;
if(op[0]=='C'){
res=query(1,st[x]);
cout<<res<<endl;
}else{
cin>>y;
change(1,st[x],ed[x],y);
}
}
}
}