1. 程式人生 > 其它 >交流分享——樹狀陣列專題

交流分享——樹狀陣列專題

樹狀陣列二分

樹狀陣列倍增

一些題目

約瑟夫問題:

選這道題的原因是這道題的標籤裡有樹狀陣列,但是沒有一個人寫樹狀陣列做法。

於是我 很閒 就去寫了。

這裡是樹狀陣列二分。

#include<bits/stdc++.h>
using namespace std;
const int N=405;
int n,m;
namespace BIT{
	int d[N];
	inline int lowbit(int x){return x&(-x);}
	inline void add(int x,int v){while(x<=n)d[x]+=v,x+=lowbit(x);}
	int query(int x){int res=0;while(x)res+=d[x],x-=lowbit(x);return res;}
	int serch(int x){
		int l=1,r=n;
		while(1){		
			if(l==r){
				if(query(l)==x) return l;
				else return -1;
			}
			else {
				int mid=(l+r)>>1;int ans=query(mid);
				if(ans>=x) r=mid;
				if(ans<x) l=mid+1;
			}
		}	
	}
}
using namespace BIT;
int a[N],cnt;bool v[N];
inline int read(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
	return x*f;
}
int main(){
	n=read();m=read();int k=n;n=n*2;
	for(int i=1;i<=n;i++)add(i,1);
	int bf=m,pos=0,res;
	while(cnt!=k){
		int limit=k-cnt;cnt++;
		int mm=m%limit==0?limit:m%limit;
		bf=mm+query(pos);
		pos=serch(bf);
		if(pos>k){add(pos,-1);add(pos-k,-1);pos=pos-k;}
		else {add(pos,-1);add(pos+k,-1);}
		printf("%d ",pos);v[pos]=1;
	}
	return 0;
}

掃描線

康拓逆展開

座右銘:我從來沒有見過這樣陰鬱而又光明的日子。