魔兽世界---屠夫(Just a Hook)
生活随笔
收集整理的這篇文章主要介紹了
魔兽世界---屠夫(Just a Hook)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Just a Hook
Time Limit: 4000/2000 MS (Java/Others)????Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 23450????Accepted Submission(s): 11742
Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of the heroes. The hook is made up of several consecutive metallic sticks which are of the same length.
Now Pudge wants to do some operations on the hook.
Let us number the consecutive metallic sticks of the hook from 1 to N. For each operation, Pudge can change the consecutive metallic sticks, numbered from X to Y, into cupreous sticks, silver sticks or golden sticks.
The total value of the hook is calculated as the sum of values of N metallic sticks. More precisely, the value for each kind of stick is calculated as follows:
For each cupreous stick, the value is 1.
For each silver stick, the value is 2.
For each golden stick, the value is 3.
Pudge wants to know the total value of the hook after performing the operations.
You may consider the original hook is made up of cupreous sticks.
?
Input The input consists of several test cases. The first line of the input is the number of the cases. There are no more than 10 cases.For each case, the first line contains an integer N, 1<=N<=100,000, which is the number of the sticks of Pudge’s meat hook and the second line contains an integer Q, 0<=Q<=100,000, which is the number of the operations.
Next Q lines, each line contains three integers X, Y, 1<=X<=Y<=N, Z, 1<=Z<=3, which defines an operation: change the sticks numbered from X to Y into the metal kind Z, where Z=1 represents the cupreous kind, Z=2 represents the silver kind and Z=3 represents the golden kind.
?
Output For each case, print a number in a line representing the total value of the hook after the operations. Use the format in the example.?
Sample Input 1 10 2 1 5 2 5 9 3?
Sample Output Case 1: The total value of the hook is 24. 題解:本來屠夫的鉤子是銅的價值是1,然后每次使x到y間的鉤子變為銀2,或金3;線段樹; 錯了很多次,原來想著把z設為全局變量,最后答案一直不對,經歷了各種曲折。。。 代碼: 1 #include<stdio.h> 2 const int MAXN=100010; 3 struct Node{ 4 int l,r; 5 int sum,lazy,val;//val不能全局變量。。。 6 }; 7 Node tree[MAXN<<2]; 8 #define NOW tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum 9 #define lson root<<1,tree[root].l,mid 10 #define rson root<<1|1,mid+1,tree[root].r 11 void build(int root,int l,int r){ 12 tree[root].l=l; 13 tree[root].r=r; 14 tree[root].lazy=0; 15 tree[root].val=0; 16 if(l==r)tree[root].sum=1; 17 else{ 18 int mid=(l+r)>>1; 19 build(lson); 20 build(rson); 21 NOW; 22 } 23 } 24 void update(int root,int l,int r,int v){ 25 if(l==tree[root].l&&r==tree[root].r){ 26 tree[root].lazy=1; 27 tree[root].val=v; 28 tree[root].sum=(r-l+1)*v; 29 } 30 else{ 31 int mid=(tree[root].l+tree[root].r)>>1; 32 if(tree[root].lazy==1){ 33 tree[root].lazy=0; 34 update(lson,tree[root].val); 35 update(rson,tree[root].val); 36 tree[root].val=0; 37 } 38 if(r<=mid)update(root<<1,l,r,v); 39 else if(l>mid)update(root<<1|1,l,r,v); 40 else{//這個不能少了,代表l,r在tree的兩個孩子節點內,也就是找到了l,r的區間; 41 update(root<<1,l,mid,v); 42 update(root<<1|1,mid+1,r,v); 43 } 44 NOW; 45 } 46 } 47 int main(){ 48 int T,N,Q,flot=0; 49 scanf("%d",&T); 50 while(T--){ 51 scanf("%d",&N); 52 scanf("%d",&Q); 53 build(1,1,N); 54 while(Q--){ 55 int x,y,z; 56 scanf("%d%d%d",&x,&y,&z); 57 update(1,x,y,z); 58 } 59 printf("Case %d: The total value of the hook is %d.\n",++flot,tree[1].sum); 60 } 61 return 0; 62 }?過了一段時間又寫了一遍,增強了自己的理解:
代碼:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<algorithm> #include<set> using namespace std; #define mem(x,y) memset(x,y,sizeof(x)) const int MAXN=100010; struct Node{int lazy,v; }; Node tree[MAXN<<2]; #define ll root<<1 #define rr root<<1|1 #define lson ll,l,mid #define rson rr,mid+1,r #define LAZY(x) tree[x].lazy #define V(x) tree[x].v int ans; void pushdown(int root,int x){if(LAZY(root)){LAZY(ll)=LAZY(root);LAZY(rr)=LAZY(root);V(ll)=LAZY(root)*(x-(x>>1));//這里錯了半天。。。。。右節點有時候要多一。。。 V(rr)=LAZY(root)*(x>>1);LAZY(root)=0;} } void pushup(int root){V(root)=V(ll)+V(rr); } void build(int root,int l,int r){LAZY(root)=0;int mid=(l+r)>>1;if(l==r){V(root)=1;return;}build(lson);build(rson);pushup(root); } void update(int root,int l,int r,int L,int R,int v){if(l>=L&&r<=R){LAZY(root)=v;V(root)=(r-l+1)*v;return;}pushdown(root,r-l+1);int mid=(l+r)>>1;/*if(mid>=R)update(lson,L,R,v);else if(mid<L)update(rson,L,R,v);else{update(lson,L,mid,v);update(rson,mid+1,R,v);}*///這樣寫也可以。。。 if(mid>=L)update(lson,L,R,v);if(mid<R)update(rson,L,R,v); pushup(root); } void query(int root,int l,int r,int L,int R){int mid=(l+r)>>1;if(l>=L&&r<=R){ans+=V(root);return;}pushdown(root,r-l+1);if(mid>=L)query(lson,L,R);if(mid<R)query(rson,L,R); } int main(){int T,N,kase=0;scanf("%d",&T);while(T--){scanf("%d",&N);build(1,1,N);int q,a,b,c;scanf("%d",&q);while(q--){scanf("%d%d%d",&a,&b,&c);update(1,1,N,a,b,c);}ans=0;query(1,1,N,1,N);//也可以不詢問直接輸出tree[1].v printf("Case %d: The total value of the hook is %d.\n",++kase,ans);}return 0; }map超時;
代碼:
#include<iostream> #include<cstdio> #include<map> #include<algorithm> using namespace std; map<int,int>mp; map<int,int>::iterator it1; const int MAXN=100010; struct Node{int s,e,v; }; Node dt[MAXN]; int main(){int T,N,q,kase=0;scanf("%d",&T);while(T--){scanf("%d",&N);for(int i=1;i<=N;i++)mp[i]=1;scanf("%d",&q);for(int i=0;i<q;i++)scanf("%d%d%d",&dt[i].s,&dt[i].e,&dt[i].v);for(int i=0;i<q;i++){for(it1=mp.lower_bound(dt[i].s);it1!=mp.end();){if(it1->first<=dt[i].e)it1->second=dt[i].v,it1++;else break;}}int ans=0;for(int i=1;i<=N;i++)ans+=mp[i];printf("Case %d: The total value of the hook is %d.\n",++kase,ans);}return 0; }過了一段時間又寫了遍,本想著一遍a的,但是錯了幾個小時,實在找不出,問了群里面的大神,原來我是x-(x>>1)沒有加括號,這就是代碼風格的問題了,我的代碼風格存在很大的問題,以至于錯誤了很難找出來,大神指出了幾點問題:
1:關于define 的括號問題;
2:關于字母與運算符的縮進問題;
3:關于宏定義的名稱問題;都存在一定問題;以后要注意了,參照谷歌的吧
另一種線段樹寫法:
extern "C++"{ #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; typedef long long LL; typedef unsigned u; typedef unsigned long long ull; #define mem(x,y) memset(x,y,sizeof(x)) void SI(double &x){scanf("%lf",&x);} void SI(int &x){scanf("%d",&x);} void SI(LL &x){scanf("%lld",&x);} void SI(u &x){scanf("%u",&x);} void SI(ull &x){scanf("%llu",&x);} void SI(char *s){scanf("%s",s);}void PI(int x){printf("%d",x);} void PI(double x){printf("%lf",x);} void PI(LL x){printf("%lld",x);} void PI(u x){printf("%u",x);} void PI(ull x){printf("%llu",x);} void PI(char *s){printf("%s",s);}#define NL puts(""); #define ll root<<1 #define rr root<<1|1 #define lson ll,l,mid #define rson rr,mid+1,r const int INF=0x3f3f3f3f; const int MAXN=100010; int tree[MAXN<<2]; int lazy[MAXN<<2]; } /* void pushup(int root){tree[root]=tree[ll]+tree[rr]; } void pushdown(int root,int x){if(lazy[root]){lazy[ll]=lazy[root];lazy[rr]=lazy[root];// tree[ll]=lazy[root]*(mid-l+1);// tree[rr]=lazy[root]*(r-mid);tree[ll]=lazy[root]*(x-(x>>1));tree[rr]=lazy[root]*(x>>1);lazy[root]=0;} } void build(int root,int l,int r){int mid=(l+r)>>1;lazy[root]=0;if(l==r){tree[root]=1;return ;}build(lson);build(rson);pushup(root); } void update(int root,int l,int r,int L,int R,int C){if(l>=L&&r<=R){tree[root]=(r-l+1)*C;lazy[root]=C;return ;}int mid=(l+r)>>1;pushdown(root,r-l+1);if(mid>=L)update(lson,L,R,C);if(mid<R)update(rson,L,R,C);pushup(root); } */ void pushdown(int root){lazy[ll] = lazy[rr] = lazy[root];lazy[root] = 0; } void update(int root,int l,int r,int L,int R,int C){if(l >= L && r <= R){lazy[root] = C;return;}if(lazy[root])pushdown(root);int mid = (l + r) >> 1;if(mid >= L)update(lson,L,R,C);if(mid < R)update(rson,L,R,C); } int sum(int root,int l,int r){int mid = (l + r) >> 1;if(lazy[root])return (r - l + 1) * lazy[root];return sum(lson) + sum(rson); } int main(){//assert(false);int T,kase=0;int N,M;SI(T);while(T--){SI(N);lazy[1]=1;SI(M);int a,b,c;while(M--){scanf("%d%d%d",&a,&b,&c);update(1,1,N,a,b,c);}printf("Case %d: The total value of the hook is %d.\n",++kase,sum(1,1,N));}return 0; }?java超時了。。。
注意:左右查找都是mid判斷的。。。注意lazy要把左右支lazy
代碼:
import java.util.Scanner;public class hdoj1698{public static void main(String[] argv){Scanner cin = new Scanner(System.in);SegmentTree atree = new SegmentTree(100010 << 2);int T, N, q;T = cin.nextInt();int kase = 0;while(T-- > 0){N = cin.nextInt();atree.build(1, 1, N);q = cin.nextInt();while(q-- > 0){int a, b, c;a = cin.nextInt();b = cin.nextInt();c = cin.nextInt();atree.update(1, 1, N, a, b, c);}// System.out.println(atree.tree[1]); System.out.println("Case " + (++kase) + ": The total value of the hook is " + atree.query(1, 1, N, 1, N) + ".");}} }class SegmentTree{private int[] tree;private int[] lazy;public SegmentTree(int size) {tree = new int[size];lazy = new int[size];}private void pushup(int root){tree[root] = tree[root << 1] + tree[root<<1 | 1];}private void pushdown(int root, int x){if(lazy[root] != 0){lazy[root << 1] = lazy[root << 1|1] = lazy[root];tree[root << 1] = (x - (x >> 1))*lazy[root];tree[root << 1|1] = (x >> 1)*lazy[root];lazy[root] = 0;}}public void build(int root, int l, int r){lazy[root] = 0;if(l == r){tree[root] = 1;return ;}int mid = (l + r) >> 1;build(root << 1, l, mid);build(root << 1|1, mid + 1, r);pushup(root);}public void update(int root, int l, int r, int L, int R, int v){if(l >= L && r <= R){tree[root] = (r - l + 1)*v;lazy[root] = v;return;}pushdown(root, r - l + 1);int mid = (r + l) >> 1;if(mid >= L){update(root << 1, l, mid, L, R, v);}if(mid < R){update(root << 1|1, mid + 1, r, L, R, v);//日了狗了。。。。。。。。。。 }pushup(root);}public int query(int root, int l, int r, int L, int R){if(l >= L && r <= R){return tree[root];}pushdown(root, r - l + 1);int sum = 0;int mid = (l + r) >> 1;if(mid >= L){sum += query(root << 1, l, mid, L, R);}if(mid < R){sum += query(root << 1|1, mid +1, r, L, R);}return sum;}}?
轉載于:https://www.cnblogs.com/handsomecui/p/4814792.html
總結
以上是生活随笔為你收集整理的魔兽世界---屠夫(Just a Hook)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 排序算法不稳定
- 下一篇: JavaScript闭包的底层运行机制