首页 > 代码库 > HDU 3340 Rain in ACStar 线段树+简单几何?
HDU 3340 Rain in ACStar 线段树+简单几何?
所有的“雨点”最后都可以分解成梯形(三角形就是其中一个底为0),然后lazy标记设置成梯形的上底和下底就好。数目很大,当然要离散化,注意处理点和点之间线段的关系,而且向下更新还有下放标记的时候要注意更新的过程中标记是有可能会变的。
#include <cstdio>#include <cstring>#include <iostream>#include <map>#include <set>#include <vector>#include <string>#include <queue>#include <deque>#include <bitset>#include <list>#include <cstdlib>#include <climits>#include <cmath>#include <ctime>#include <algorithm>#include <stack>#include <sstream>#include <numeric>#include <fstream>#include <functional>using namespace std;#define MP make_pair#define PB push_back#define lson rt << 1,l,mid#define rson rt << 1 | 1,mid + 1,rtypedef long long LL;typedef unsigned long long ULL;typedef vector<int> VI;typedef pair<int,int> pii;const int INF = INT_MAX / 3;const double eps = 1e-8;const LL LINF = 1e17;const double DINF = 1e60;const int maxn = 25000 + 10;const int maxv = maxn * 10;VI numx;vector<pii> rpoint[maxn];char cmd[maxn];int ql[maxn],qr[maxn],n,cnt[maxn];double lbd[maxv << 2], rbd[maxv << 2], sum[maxv << 2];int len[maxv << 2],knumx;int getID(int Val) { return lower_bound(numx.begin(),numx.end(),Val) - numx.begin();}void input() { int nx,ny; numx.clear(); scanf("%d",&n); for(int i = 1;i <= n;i++) { scanf(" %c",&cmd[i]); if(cmd[i] == ‘Q‘) { scanf("%d%d",&ql[i],&qr[i]); numx.PB(ql[i]); numx.PB(qr[i]); } else { scanf("%d",&cnt[i]); rpoint[i].clear(); for(int j = 0;j < cnt[i];j++) { scanf("%d%d",&nx,&ny); rpoint[i].PB(MP(nx,ny)); numx.PB(nx); } } } sort(numx.begin(),numx.end()); numx.erase(unique(numx.begin(),numx.end()),numx.end());}void pushup(int rt) { sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];}void pushdown(int rt) { int lc = rt << 1, rc = rt << 1 | 1; double mid = lbd[rt] + (rbd[rt] - lbd[rt]) * len[lc] / len[rt]; lbd[lc] += lbd[rt]; rbd[lc] += mid; lbd[rc] += mid; rbd[rc] += rbd[rt]; sum[lc] += (lbd[rt] + mid) * len[lc] / 2; sum[rc] += (mid + rbd[rt]) * len[rc] / 2; lbd[rt] = rbd[rt] = 0;}void build(int rt,int l,int r) { len[rt] = numx[r + 1] - numx[l]; if(l == r) return; int mid = (l + r) >> 1; build(lson); build(rson);}void update(int rt,int l,int r,int ql,int qr,double ld,double rd) { if(ql == l && qr == r) { lbd[rt] += ld; rbd[rt] += rd; sum[rt] += (ld + rd) * len[rt] / 2; } else { pushdown(rt); int mid = (l + r) >> 1; if(qr <= mid) update(lson,ql,qr,ld,rd); else if(ql > mid) update(rson,ql,qr,ld,rd); else { double midv = ld + (rd - ld) * (numx[mid + 1] - numx[ql]) / (numx[qr + 1] - numx[ql]); update(lson,ql,mid,ld,midv); update(rson,mid + 1,qr,midv,rd); } pushup(rt); }}double query(int rt,int l,int r,int ql,int qr) { if(ql <= l && qr >= r) return sum[rt]; else { int mid = (l + r) >> 1; double ret = 0; pushdown(rt); if(ql <= mid) ret += query(lson,ql,qr); if(qr > mid) ret += query(rson,ql,qr); return ret; }}void Handle(vector<pii> &sp,int cnt) { sp.PB(sp[0]); for(int i = 0;i < cnt;i++) { pii now = sp[i], nxt = sp[i + 1]; if(now.first < nxt.first) { int x1 = getID(now.first), x2 = getID(nxt.first) - 1; update(1,0,knumx - 1,x1,x2,-now.second,-nxt.second); } if(now.first > nxt.first) { int x1 = getID(nxt.first), x2 = getID(now.first) - 1; update(1,0,knumx - 1,x1,x2,nxt.second,now.second); } }}void solve() { knumx = numx.size() - 1; build(1,0,knumx - 1); memset(lbd,0,sizeof(lbd)); memset(rbd,0,sizeof(rbd)); memset(sum,0,sizeof(sum)); for(int i = 1;i <= n;i++) { if(cmd[i] == ‘Q‘) { int x1 = getID(ql[i]), x2 = getID(qr[i]) - 1; printf("%.3f\n",query(1,0,knumx - 1,x1,x2)); } else Handle(rpoint[i],cnt[i]); }}int main() { int T; scanf("%d",&T); while(T--) { input(); solve(); } return 0;}
HDU 3340 Rain in ACStar 线段树+简单几何?
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。