Fenwick
hdu1394 这题说的是给了一个序列计算这个序列的逆序对总共要进行n次 每次都将目前的第一个放到序列的最后一个位置然后 计算一次逆序对 这样我们只需要先求一次逆序对 然后接着每次都用F=F+(n-T[i]-1)+T[i] 求得下一个 就不需要每次都去算逆序对
- #include <iostream>
- #include <cstdio>
- #include <string.h>
- using namespace std;
- const int maxn = ;
- int C[];
- int T[];
- int n;
- int lowbit(int x){
- return x&(-x);
- }
- int sum(int x){
- int ret = ;
- while(x>){
- ret+=C[x]; x-=lowbit(x);
- }
- return ret;
- }
- void add(int x,int d){
- while(x<=n){
- C[x]+=d; x+=lowbit(x);
- }
- }
- int Fenwick(int st){
- int ans =;
- for(int i = ;i<n ;++ i){
- add(T[(st+i)%n],);
- int S1=sum(n);
- int S2 =sum(T[(st+i)%n]);
- ans+=S1-S2;
- }
- return ans;
- }
- int main()
- {
- while(scanf("%d",&n) == ){
- int ans =0x7fffffff;
- for(int i = ; i< n ;++ i){
- scanf("%d",&T[i]);
- ++T[i];
- }
- memset(C,,sizeof(C));
- int f=Fenwick();
- for(int i= ; i<n ;++i){
- f=f+n-T[i]-(T[i]-);
- ans =min(ans,f);
- }
- printf("%d\n",ans);
- }
- return ;
- }
acdream1127 这题说的是给了两个 大站点 在大站点的他们附近有许多的小站点 小站点只能通过大站点与外界通信 大站点有一个圆形的作用范围 这个范围内的点可以接受信息 范围外的不能好了就这样,这样他给了很多个不同的半径 计算在每个半径不同的情况下又多少个点不在范围内 因为有两个点所以 每个点就形成了与他们距离 的一个二维的相对坐标,当他不在第一个点的坐标内的时候我们可以将他 放进 第二维的树状数组中 通过求和判断是否在第二维的相应的坐标里这样我们 用 第二点的半径所在的位置去进行一次求和 和 总数n sum(n)得到的是 目前不在 第一个范围内的点的个数sum(第二个半径的位置) 得到的是在第二个范围内点的个数 然后相减一下就得到了
- #include <iostream>
- #include <cstdio>
- #include <string.h>
- #include <algorithm>
- using namespace std;
- const int maxn=;
- int C[maxn],N;
- struct node{
- long long x,y;
- int num;
- bool operator <(const node &A)const {
- return x>=A.x;
- }
- }P[maxn],Query[maxn];
- long long dist[maxn];
- bool cmp1(node A,node B){
- return A.x >= B.x ;
- }
- int lowbit(int x){
- return x&(-x);
- }
- void add(int x,int d){
- while(x<=N){
- C[x]+=d; x+=lowbit(x);
- }
- }
- int sum(int x){
- int ans =;
- while(x>){
- ans+=C[x];
- x-=lowbit(x);
- }
- return ans;
- }
- int ans[maxn];
- int main()
- {
- long long x1,y1,x2,y2;
- while(scanf("%I64d%I64d%I64d%I64d",&x1,&y1,&x2,&y2)==){
- scanf("%d",&N);
- for(int i = ; i<N; ++ i){
- long long x,y;
- scanf("%I64d%I64d",&x,&y);
- P[i].x=(x-x1)*(x-x1)+(y-y1)*(y-y1);
- P[i].y=(x-x2)*(x-x2)+(y-y2)*(y-y2);
- dist[i+]=P[i].y;
- }
- int M;
- scanf("%d",&M);
- for(int i = ; i<M; ++i){
- long long r1,r2;
- scanf("%I64d%I64d",&r1,&r2);
- Query[i].x=r1*r1;
- Query[i].y=r2*r2;
- Query[i].num=i;
- }
- sort(P,P+N,cmp1);
- sort(dist+,dist++N);
- int num=unique(dist+,dist++N)--dist;
- sort(Query,Query+N,cmp1);
- int id=;
- memset(C,,sizeof(C));
- for(int i =; i<M; ++ i) {
- while( id<N && P[id].x >= Query[i].x ) {
- int loc = lower_bound( dist + , dist++num, P[id].y )-dist;
- add(loc,);
- ++id;
- }
- int lox = lower_bound(dist + , dist++num, Query[i].y)-dist-;
- int SN =sum(N);
- int SLOX =sum(lox);
- ans[Query[i].num] = SN -SLOX;
- }
- for(int i =; i<M; ++i)
- printf("%d\n",ans[i]);
- }
- return ;
- }
#247div2 E 题 这题说的是 有n个试管每个试管中有一些汞 然后又两种操作 第一种是将某个试管中的汞的体积变成 xi 然后将第二种操作是将 Vi 升的水倒入 这n个试管中求 有装水的试管中水的体积最大的 体积最小, 这样我们可以去二分找这个可能的高度 ,将所有可能的高度进行一次离散化,然后不断的用树状数组去修改和查询,然后得到了正解
- #include <iostream>
- #include <cstdio>
- #include <string.h>
- #include <set>
- #include <map>
- using namespace std;
- const int maxn=;
- int h[maxn],T[],n,q,max_h=;
- int p[],x[],cap[maxn];
- __int64 V[];
- __int64 A[maxn],B[maxn];
- int lowbit(int x){
- return x&(-x);
- }
- void add(__int64 *C, int x,__int64 d){
- while(x<=max_h){
- C[x]+=d; x+=lowbit(x);
- }
- }
- __int64 sum(__int64 *C,int x){
- __int64 ans=;
- while(x>){
- ans+=C[x]; x-=lowbit(x);
- }
- return ans;
- }
- __int64 solve(int H){
- __int64 num=sum(A,H);
- __int64 remain = sum(B,H);
- __int64 line=cap[H];
- __int64 ans = num * line - remain;
- return ans;
- }
- int main()
- {
- set<int>Live;
- scanf("%d%d",&n,&q);
- for(int i =; i<=n; ++i){
- scanf("%d",&h[i]);
- Live.insert(h[i]);
- }
- for( int i =; i<q; ++i){
- scanf("%d",&T[i]);
- if(T[i] == ){
- scanf("%d%d",&p[i],&x[i]);
- Live.insert(x[i]);
- }else scanf("%I64d",&V[i]);
- }
- map<int,int>MP;
- for(set<int>::iterator it=Live.begin(); it!=Live.end(); ++it){
- int E = *it;
- MP.insert(make_pair(E,max_h+));
- ++max_h;
- cap[max_h] = E;
- }
- for(int i =; i<=n; ++i){
- int loc = MP[h[i]];
- add(A,loc,);
- add(B,loc,h[i]);
- }
- for(int e=; e<q; ++e){
- if(T[e]==){
- int t = p[e];
- int loc = MP[h[t]];
- add(A, loc, -);
- add(B, loc, -h[t]);
- h[t] = x[e];
- loc = MP[h[t]];
- add(A, loc, );
- add(B, loc, h[t]);
- }else{
- int H=;
- for(int i = ; i>=; -- i){
- if((H+(<<i))>max_h) continue;
- if(solve((H+(<<i)))<=V[e])
- H=H+(<<i);
- }
- double remain=solve(H);
- double num=sum(A,H);
- double ans = cap[H];
- ans =ans + (double(V[e]) - remain)/num;
- printf("%.5lf\n",ans);
- }
- }
- return ;
- }
uva1513 这 题 说 的 是 给 了 一 个 堆(从1...到n) 然 后 从 堆 中 的 某 个 位 置 取 一 个 点 出 来 放在最顶端 每次 操作时输出在该点的上方有多少个点用树状数组去查询 自然前面预留m个位置 可 以 放 后 面 堆 叠 的 在 前 面 的 然后每次操作记录一下该点所在的位置
- #include <iostream>
- #include <cstdio>
- #include <string.h>
- using namespace std;
- const int maxn=;
- int n,m,local[maxn];
- int C[maxn*],ans[maxn];
- int lowbit(int x){
- return x&(-x);
- }
- void add(int x,int d){
- while(x<=n+m){
- C[x]+=d;
- x+=lowbit(x);
- }
- }
- int sum(int x){
- int ans=;
- while(x>){
- ans+=C[x];
- x-=lowbit(x);
- }
- return ans;
- }
- int main()
- {
- int cas;
- scanf("%d",&cas);
- while( cas -- ){
- scanf("%d%d",&n,&m);
- for(int i=;i<=n+m; ++i)C[i]=;
- for(int i=; i<=n; ++i){
- local[i]=i+m;
- add(m+i,);
- }
- int len=;
- for( int i=m; i> ; --i){
- int a;
- scanf("%d",&a);
- ans[len++]=sum(local[a]-);
- add(local[a],-);
- local[a]=i;
- add(local[a],);
- }
- for(int i=;i<len-; ++i)
- printf("%d ",ans[i]);
- printf("%d\n",ans[len-]);
- }
- return ;
- }
uva11525 这个题说的是给了1到K的数列 求出这个数列 的 第n 大 当然按照字典序排列, 因为 n=Si(k-i)!+Si-1(k-(i-1))!+...S0(k-k)! 经过分析我们可以得出这样的一个结论就是Si 代表的是剩下的第几大的数 然后二分去用树状数组照这个点
- #include <iostream>
- #include<cstdio>
- #include <string.h>
- using namespace std;
- const int maxn = ;
- int n,K,S[maxn],ans[maxn],C[maxn];
- int lowbit(int x){
- return x&(-x);
- }
- void add(int x,int d){
- while(x<=K){
- C[x] += d; x+=lowbit(x);
- }
- }
- int sum(int x){
- int ans=;
- while(x>){
- ans+=C[x]; x-=lowbit(x);
- }
- return ans;
- }
- int main()
- {
- int t;
- scanf("%d",&t);
- while(t--){
- memset(C,,sizeof(C));
- scanf("%d",&K);
- for( int i=; i<K; ++i )
- scanf("%d",&S[i]);
- for(int i=; i<=K ; ++i)
- add(i,);
- for(int i=; i<K; ++i){
- int L=,R=K;
- while(L<R){
- int mid=L+((R-L)>>);
- int num=sum(mid);
- if(num>=(S[i]+))
- R=mid;
- else L=mid+;
- }
- add(L,-);
- ans[i]=L;
- }
- for(int i=;i<K-; ++i)
- printf("%d ",ans[i]);
- printf("%d\n",ans[K-]);
- }
- return ;
- }
hdu4863 这题说的是给了 一个公司有 M 个任务 但是有N 台机器每台机器 只能完成一项任务,每个任务只允许一台机器完成,每个任务有一个完成时间和等级 , 每台机器有等级和所能承受的最大时间,然后我们先将按照时间排序 时间形同的任务 ,等级大的放前面,然后每次将时间大于等于当前任务的机器的等级放入树状数组中每次去修改树状数组
- #include <iostream>
- #include <cstdio>
- #include <string.h>
- #include <algorithm>
- using namespace std;
- struct point{
- int timef,rankf;
- bool operator < (const point A) const{
- return timef>A.timef||(timef==A.timef&&rankf>=A.rankf);
- }
- }Task[],machine[];
- __int64 X[],Y[];
- int lowbit(int x){
- return x&(-x);
- }
- void add(__int64 *C, int x, int d,int N){
- while(x<=N){
- C[x]+=d; x+=lowbit(x);
- }
- }
- __int64 sum(__int64 *C, int x){
- __int64 ans=;
- while(x>){
- ans+=C[x]; x-=lowbit(x);
- }
- return ans;
- }
- bool bit_time(int D)
- {
- __int64 zong = sum(X,);
- __int64 di=sum(X,D-);
- if(zong-di<=)return false;
- // add(X,D,-1,1440);
- return true;
- }
- bool bit_rank(int D)
- {
- __int64 zong = sum(Y,);
- __int64 di = sum(Y,D-);
- __int64 er = zong-di;
- if(er<=)return false;
- int L = D , R =;
- while(L<R){
- int mid=(R+L)/;
- __int64 W =sum(Y,mid)-di;
- if(W==)L=mid+;
- else R=mid;
- }
- add(Y,L,-,);
- return true;
- }
- void solve(int N,int M)
- {
- __int64 ans=;
- int s=,num=;
- for(int i=; i<N; ++i)
- {
- add(X,machine[i].timef,,);
- }
- for(int i=; i<M; ++i){
- while(s<N&&machine[s].timef>=Task[i].timef){
- add(Y,machine[s].rankf,,);
- s++;
- }
- if(bit_time(Task[i].timef)){
- if(bit_rank(Task[i].rankf)){
- add(X,Task[i].timef,-,);
- ans+= *Task[i].timef+*(Task[i].rankf-);
- num++;
- }
- }
- }
- printf("%d %I64d\n",num,ans);
- }
- int main()
- {
- int N,M;
- while(scanf("%d%d",&N,&M)==)
- {
- memset(X,,sizeof(X));
- memset(Y,,sizeof(Y));
- for(int i = ; i<N; ++i){
- scanf("%d%d",&machine[i].timef,&machine[i].rankf);
- machine[i].rankf++;
- }
- for(int i=; i<M; ++i){
- scanf("%d%d",&Task[i].timef,&Task[i].rankf);
- Task[i].rankf++;
- }
- sort(machine,machine+N);
- sort(Task,Task+M);
- solve(N,M);
- }
- return ;
- }
- /*
- 3 4
- 100 3
- 101 2
- 99 2
- 99 3
- 100 3
- 100 2
- 99 2
- */
cf459D 题说的是 计算 [1,i] 中 值等于ai 的个数 x1, 求出[j,n]中 aj的 个数 x2 其中i小于 j 然后求出,使得x1小于x2的ij的对数,首先对数组进行离散然后,从后往前每个位子都将从该位置的aj以及该位置以后aj的个数,插入树状数组中去,然后 枚举每一个i并将相应的aj个数从 树状数组中删去然后 对于每一个ai个数 在数组中找出小于该个数长度的数有多少个,每次加起来就可以了
的
Fenwick的更多相关文章
- POJ 3321 Apple Tree DFS序+fenwick
题目大意:有一颗长满苹果的苹果树,有两个操作. 1.询问以一个点为根的子树中有多少个苹果. 2.看看一个点有没有苹果,假设没有苹果.那么那里就立即长出一个苹果(= =!):否则就把那个苹果摘下来. 思 ...
- Kattis - Fenwick Tree(树状数组区间更新单点求值)
Fenwick Tree Input The first line of input contains two integers NN, QQ, where 1≤N≤50000001≤N≤500000 ...
- Binary Indexed Tree (Fenwick Tree)
Binary Indexed Tree 主要是为了存储数组前缀或或后缀和,以便计算任意一段的和.其优势在于可以常数时间处理更新(如果不需要更新直接用一个数组存储所有前缀/后缀和即可).空间复杂度O(n ...
- [bzoj1012](JSOI2008)最大数maxnumber(Fenwick Tree)
Description 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度. 2. ...
- Fenwick Tree / Binary Indexed Tree
Motivation: Given a 1D array of n elements. [2, 5, -1, 3, 6] range sum query: what's the sum from 2n ...
- 315. Count of Smaller Numbers After Self(Fenwick Tree)
You are given an integer array nums and you have to return a new counts array. The counts array has ...
- LA 5902 - Movie collection 树状数组(Fenwick树)
看题传送门 题目大意:XXX喜欢看电影,他有好多好多的影碟,每个影碟都有个独立的编号.开始是从下往上影碟的顺序是n~1,他每次拿出影碟的时候,你需要输出压在该影碟上的有几个.(拿出后其他影碟顺序不变) ...
- LA 4329 - Ping pong 树状数组(Fenwick树)
先放看题传送门 哭瞎了,交上去一直 Runtime error .以为那里错了. 狂改!!!!! 然后还是一直... 继续狂改!!!!... 一直.... 最后发现数组开小了.......... 果断 ...
- 树状数组,Fenwick Tree
Fenwick Tree, (also known as Binary Indexed Tree,二叉索引树), is a high-performance data structure to cal ...
随机推荐
- C语言位操作--奇偶校验算法
信息是以比特流的方式传输的,类似01000001.在传输过程中,有可能会发生错误,比如,我们存储了01000001,但是取出来却是01000000,即低位由0变成了1.为了检测到这种错误,我们可以通过 ...
- JavaScript—当前时间
当前时间-倒计时下载 效果: 代码: <!doctype html> <html> <head> <meta http-equiv="Content ...
- 【CF889E】Mod Mod Mod DP
[CF889E]Mod Mod Mod 题意:给你一个序列$a_1,a_2...a_n$,定义$f(x,n)=x\mod a_n$,$f(x,i)=x\mod a_i+f(x \mod a_i,i+1 ...
- nodeJS删除文件
var fs = require("fs"); var path = require("path"); deleteFolderRecursive = func ...
- tomcat+redis会话共享
1.基础环境: jdk1. tomcat7 redis nginx 2.添加依赖的jar包到tomcat的lib目录(http://pan.baidu.com/s/1eRAwN0Q) 3.配置tomc ...
- Twig---和vue或angular前端框架并存
<h1> {% verbatim %} {{message}} {% endverbatim %} </h1> 上面这种方式虽然能够解决,前台渲染的问题,但是还是会报错: 第二 ...
- vue--环境搭建(创建运行项目)
如何搭建vue环境: 1.安装之前必须要安装 node.js 2.搭建Vue环境,安装vue的脚手架工具 npm install --global vue-cli / cnpm install --g ...
- 纯CSS绘制的三角形箭头图案【原创】
参考:http://www.webhek.com/css-triangles/ 使用上下左右的三角形箭头标志,直接用css即可完成,直接附上代码. css: div#up { width: 0px; ...
- 线性DP总结(LIS,LCS,LCIS,最长子段和)
做了一段时间的线性dp的题目是时候做一个总结 线性动态规划无非就是在一个数组上搞嘛, 首先看一个最简单的问题: 一,最长字段和 下面为状态转移方程 for(int i=2;i<=n;i++) { ...
- textField placeholder颜色,位置设置
自定义textField继承自UITextField 重写 - (CGRect)placeholderRectForBounds:(CGRect)bounds _phoneTF.font = HPFo ...