不會做啊!打了個貪心,沒有加倍增,然後在打了幾個特殊情況拿了85分。
其實答案有乙個性質:區間的定位個數=2*區間的長度-完全被包含的區間個數,比如說[2,7]的答案=(7-2+1)*2-9=3,包含的區間([2,2],[3,3],[4,4],[5,5],[2,3],[5,7],[6,7],[6,6],[7,7])。
好神奇啊!
為什麼nie?(感覺我是個弱智)
乙個線段樹中的區間[l,r],包括他自己和下面的區間一共有2*(r-l+1)-1個區間,所以我用2*(r-l+1)減去這些完全被包含的區間個數就會的出乙個1。對於詢問的[l,r],因為不一定是線段樹中的區間,所以含有很多棵樹,乙個樹可以用乙個1來表示(就相當於用乙個已經最大的區間來包含),這些樹的集合是所有被包含在這個區間的區間的個數(及所有[l』,r』]的區間滿足l』≥l,r』≤r)。
這個二元偏序關係的計數,可以用樹狀陣列來實現,把所有的詢問和區間按照左端點排序,然後限制l的關係,把所有的r放進樹狀陣列裡面,然後查詢一下就好了。
#include
#include
#include
#include
#include
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fod(i,a,b) for(i=a;i>=b;i--)
#define rep(i,a) for(i=first[a];i;i=next[i])
using
namespace
std;
const
int maxn=100007;
int i,j,k,n,m,ans[maxn],l,r;
int a[maxn],dfn,tongl,tongr;
int num;
int t[maxn*30];
struct nodeduan[maxn*30],wen[maxn];
void build(int x,int l,int r)
int mid=a[++dfn];
build(x*2,l,mid);
build(x*2+1,mid+1,r);
duan[++num].l=l,duan[num].r=r;
}bool cmp(node x,node y)
void add(int x,int y)
int find(int x)
int main()
build(1,1,n);
fo(i,1,m)scanf("%d%d",&wen[i].l,&wen[i].r),wen[i].c=i;
sort(wen+1,wen+1+m,cmp);
sort(duan+1,duan+1+num,cmp);
k=1;
fo(i,1,num)add(duan[i].r,1);
fo(i,1,m)
fo(i,1,m)printf("%d\n",ans[i]);
}
NOIP模擬 排列 權值線段樹
題目大意 對於乙個1到n的排列,若知道每一位的逆序數 第i位a i 的逆序數就是a 1 a i 1 中比a i 大的數的個數 則能求出原排列。現在對於排列,給出。p i 表示a 1 a i 的逆序數和。請你求出原排列。1 n 100000 解題思路 先求出每個數的逆序數,仍設為p i 倒著確定,那對...
NOIP模擬 奇襲 線段樹 單調棧
題意 給定數列,求有多少個區間滿足區間最大 1 區間最小 區間長度 滿足條件為 m ax 1 m in r 1 l ma x mi n r lmax 1 min r 1 l max min r l max 1 min r 1 l ma x mi n r lma x mi n l rmax min l...
Jzoj4747 被粉碎的線段樹
額這個題麼 有乙個很關鍵的點 結點個數依然為2n 1 證明可以看sam的講稿 不難發現以下性質 區間定位個數 區間所覆蓋的節點個數 2 區間長度 所以問題變為,乙個區間覆蓋了多少個節點?我們可以求出所有的節點,然後這個問題就是乙個二維偏序計數問題了 具體用離線 按照r排序套上樹狀陣列即可 inclu...