這個題是一個理解二維線段樹的好題,其實二維線段樹不難
先建立一顆線段樹,然後每個節點下又有一個線段樹,看看代碼很容易理解的,以前總不想去看
先查找身高符合要求的,然後再查找活潑值符合要求中緣分值最大的
代碼很簡單,只是比普通的線段樹多了點
/* * File: main.cpp * Author: Mi * * Created on 2011年3月30日, 下午12:59 */ #include <cstdlib> #include <stdio.h> #include <algorithm> #define N 1005 using namespace std; /* * */ double max(double a,double b) {return a>b?a:b;} struct tree_y { int l,r; double max; int mid() { return (l+r)>>1; } }; struct tree_x { int l,r; tree_y Y[N*4]; int mid() { return (l+r)>>1; } }X[405]; void build_y(tree_x &x,int l,int r,int root) { x.Y[root].l=l; x.Y[root].r=r; x.Y[root].max=-1; if(l==r) return ; int mid=x.Y[root].mid(); build_y(x,l,mid,root<<1); build_y(x,mid+1,r,root<<1|1); } void build_x(int l,int r,int root) { X[root].l=l,X[root].r=r; build_y(X[root],1,1001,1); if(l==r) return ; int mid=X[root].mid(); build_x(l,mid,root<<1); build_x(mid+1,r,root<<1|1); } void modify_y(tree_x &x,int a,int root,double luck) { if(luck>x.Y[root].max) x.Y[root].max=luck; if(x.Y[root].l==x.Y[root].r) return ; int mid=x.Y[root].mid(); if(a<=mid) modify_y(x,a,root<<1,luck); else modify_y(x,a,root<<1|1,luck); x.Y[root].max=max(x.Y[root<<1].max,x.Y[root<<1|1].max); } void modify_x(int h,int a,int root,double luck) { modify_y(X[root],a,1,luck); if(X[root].l==X[root].r) return ; int mid=X[root].mid(); if(h<=mid) modify_x(h,a,root<<1,luck); else modify_x(h,a,root<<1|1,luck); } double query_y(tree_x &x,int al,int ar,int root) { if(x.Y[root].l==al&&x.Y[root].r==ar) return x.Y[root].max; int mid=x.Y[root].mid(); if(ar<=mid) return query_y(x,al,ar,root<<1); else if(al>=mid+1) return query_y(x,al,ar,root<<1|1); else { double x1,x2; x1=query_y(x,al,mid,root<<1); x2=query_y(x,mid+1,ar,root<<1|1); return max(x1,x2); } return -1; } double query_x(int hl,int hr,int al,int ar,int root) { if(X[root].l==hl&&X[root].r==hr) return query_y(X[root],al,ar,1); int mid=X[root].mid(); if(hr<=mid) return query_x(hl,hr,al,ar,root<<1); else if(hl>=mid+1) return query_x(hl,hr,al,ar,root<<1|1); else { double x1,x2; x1=query_x(hl,mid,al,ar,root<<1); x2=query_x(mid+1,hr,al,ar,root<<1|1); return max(x1,x2); } return -1; } int main(int argc, char** argv) { int n; while(scanf("%d",&n),n) { build_x(1,101,1); for(int i=1;i<=n;i++) { char str[2]; scanf("%s",str); if(str[0]=='I') { int h; double a,l; scanf("%d%lf%lf",&h,&a,&l); modify_x(h-99,int(a*10)+1,1,l); } else { int hl,hr; double al,ar,ans; scanf("%d%d%lf%lf",&hl,&hr,&al,&ar); if(hl>hr) swap(hl,hr); if(al>ar) swap(al,ar); ans=query_x(hl-99,hr-99,int(al*10)+1,int(ar*10)+1,1); if(ans<0) puts("-1"); else printf("%.1lf/n",ans); } } } return 0; }
洛谷傳送門 Atcoder傳送門 題目大意 數軸上有NNN個點,每個點初始時在位置XiX_iXi,以ViV_iVi的速度向數軸正方向前進 初始時刻,你可以選擇一些點爲其染色,之後的行走過程中,染色的點會將其碰到的所有點都染上色
思路: 明顯枚舉每個端點作爲騷區間的左端點,假設我們枚舉ai作爲左端點,然後在他右邊找到第一個小於ai的數的位置x,然後再在x的右邊找第一個小於ai的數的位置y,明顯以ai爲左端點的騷區間只能在[x,y)這個區間中選擇右端點,同理
一道比較簡單的線段樹,不過寫了好長時間,build時 lson 和 rson 忘了賦值,沒有更新num ,看來水題也是要認真寫的 用了hash來記錄沒一點在樹中對應的節點,有葉子節點向根節點更新 #include <iostream>
先放代碼,日後更。(*2) ===========================2018.3.21UPD=========================== 題面在這裏 做法 容易發現只要將query的l−1,rl−1,r
一、Problem 給你一個字符串 num 和一個整數 k 。其中,num 表示一個很大的整數,字符串中的每個字符依次對應整數上的各個 數位 。 你可以交換這個整數相鄰數位的數字 最多 k 次。 請你返回你能得到的最小整數,並以字
原題目鏈接 題意是給你一棵樹,然後有兩類操作,一種是將某個節點以及它所有的子孫修改成某個數,另一種是查詢該節點的值。所有節點的初始值爲-1; 思路 說實話不好聯想到線段樹上來,如果用暴力修改每棵子樹的話每次修改的複雜度都可以達到
思路:我們再線段樹裏面去維護一個區間有多少個數和他的最大值最小值,區間查詢的時候我們去看有多少個數,如果他的數大於R,那麼我們去他的左子樹,如果他的數小於L我們去他的右子樹,都不是的話我們去看他左子樹此時要查詢的數變成L——左子
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1152 Solved: 586 Description 松鼠的新家是一棵樹,
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1374 Solved: 503 Description 給出一個n個節點的有根樹
題目描述現給定n個閉區間[ai, bi],1<=i<=n。這些區間的並可以表示爲一些不相交的閉區間的並。你的任務就是在這些表示方式中找出包含最少區間的方案。你的輸出應該按照區間的升序排列。這裏如果說兩個區間[a, b]和[c, d]是按照
Description 酷愛日料的小Z經常光顧學校東門外的回轉壽司店。在這裏,一盤盤壽司通過傳送帶依次呈現在小Z眼前。不同的壽 司帶給小Z的味覺感受是不一樣的,我們定義小Z對每盤壽司都有一個滿意度,例如小Z酷愛三文魚,他對一盤三文 魚壽司
Description 現在請求你維護一個數列,要求提供以下兩種操作:1、 查詢操作。語法:Q L 功能:查詢當前數列中末尾L個數中的最大的數,並輸出這個數的值。限制:L不超過當前數列的長度。2、 插入操作。語法:A n 功能:將n加上
傳送門biu~ 用線段樹維護使用編號在[l,r]內的道路最終會選擇哪些道路。即線段樹每個節點記錄一個邊的集合,集合大小顯然不超過n。 在合併兩個區間的時候採用Kruskal用歸併的方式合併(暴力)。 #include<bits
Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s)
這個題方法很簡單啊,可是沒有考慮 0 1 這個例子,就wr了整整一下午 寫個博客紀念一下 /* 線段樹維護區間最小值 貪心:每次找可行區域的最小值 */ #include<cstdio> #include<cstring> #in