【线段树】扇形面积并(P3997)
生活随笔
收集整理的這篇文章主要介紹了
【线段树】扇形面积并(P3997)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
正題
P3997
題目大意
給若干扇形,問你疊了至少k次的面積
解題思路
把園展開,然后用線段樹維護(hù)每個(gè)點(diǎn)的出現(xiàn)次數(shù)
當(dāng)最大次數(shù)大于k,用log的時(shí)間查找該點(diǎn),然后計(jì)算結(jié)果,因?yàn)樽疃嘀挥?*n次查找,所以不會(huì)TLE
code
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #define N 100010 using namespace std; ll n,m,k,ans; struct node {ll r,s,t; }a[N]; bool cmp(node a,node b) {return a.r>b.r; } struct Tree {#define ls x*2#define rs x*2+1ll mx[N*10<<3],lazy[N*10<<3];void push_up(ll x){mx[x]=max(mx[ls],mx[rs]);return;}void push_down(ll x){if(lazy[x]){lazy[ls]+=lazy[x];lazy[rs]+=lazy[x];mx[ls]+=lazy[x];mx[rs]+=lazy[x];lazy[x]=0;}return;}void get(ll x,ll l,ll r,ll rr){if(l==r){ans+=rr*rr;mx[x]=-1000000000;return;}push_down(x);ll mid=l+r>>1;if(mx[ls]>=k)get(ls,l,mid,rr);if(mx[rs]>=k)get(rs,mid+1,r,rr);push_up(x);return;}void add(ll x,ll L,ll R,ll l,ll r,ll rr){if (L==l&&R==r){lazy[x]++;mx[x]++;if(mx[x]>=k)get(x,L,R,rr);return;}push_down(x);ll mid=L+R>>1;if(r<=mid)add(ls,L,mid,l,r,rr);else if(l>mid)add(rs,mid+1,R,l,r,rr);else add(ls,L,mid,l,mid,rr),add(rs,mid+1,R,mid+1,r,rr);push_up(x);return;} }T; int main() {scanf("%lld%lld%lld",&n,&m,&k);for(ll i=1;i<=n;++i){scanf("%lld%lld%lld",&a[i].r,&a[i].s,&a[i].t);if(a[i].t==-m)a[i].t=m-1;else a[i].t--;if(a[i].s==m)a[i].s=-m;if(a[i].s>=0)a[i].s=m-a[i].s;else a[i].s=m-a[i].s;if(a[i].t>=0)a[i].t=m-a[i].t;else a[i].t=m-a[i].t;swap(a[i].s,a[i].t);n++;n--;}sort(a+1,a+1+n,cmp);for(ll i=1;i<=n;++i){if(a[i].s>a[i].t){T.add(1,1,m*2,a[i].s,m*2,a[i].r);T.add(1,1,m*2,1,a[i].t,a[i].r);}else T.add(1,1,m*2,a[i].s,a[i].t,a[i].r);}printf("%lld",ans);return 0; }總結(jié)
以上是生活随笔為你收集整理的【线段树】扇形面积并(P3997)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【图论】Tree之最小方差树(bzoj
- 下一篇: 【双指针】Square Pasture