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 ...
随机推荐
- js 的基础知识
一.弱类型意识 js变量是没有类型的 var a = 1; //a 就是一个变量 不要提什么类型 变量可以赋任何类型的值 类型仅仅是值的性质 与变量无关 Js的基本类型 变量未赋值时,其值为und ...
- list,set中可以存放Object类型对象
List<JSONObject> series = new ArrayList<JSONObject>();
- POJ-1952 BUY LOW, BUY LOWER(线性DP)
BUY LOW, BUY LOWER Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 9244 Accepted: 3226 De ...
- 使用IntelliJ IDEA进行Python远程调试的需求(未完)
使用IntelliJ IDEA进行Python远程调试的需求(未完) 在研究深度学习Machlearning时,有时候需要借助ubuntu搭建的tensorflow环境,另外也有越来越多的运算程序只能 ...
- 源码 ServerParameter
总结 1. 服务器参数类型和设置时刻 https://github.com/mongodb/mongo/blob/master/src/mongo/db/server_parameters.h // ...
- Python爬虫实例(六)多进程下载金庸网小说
目标任务:使用多进程下载金庸网各个版本(旧版.修订版.新修版)的小说 代码如下: # -*- coding: utf-8 -*- import requests from lxml import et ...
- Time Profiler Instrument分析卡顿
https://www.jianshu.com/p/080108c969e8 启动Time Profile:Xcode ——> Product ——> Profile ——> Tim ...
- oracle数据迁移到mysql
今天遇到需求要把oracle的部分数据搬到mysql,用java代码抓数据,然后拼接成sql语句,然后用navicat执行sql脚本的方法,导入数据库. import oracle.jdbc.driv ...
- Java GUI程序设计
在实际应用中,我们见到的许多应用界面都属于GUI图形型用户界面.如:我们点击QQ图标,就会弹出一个QQ登陆界面的对话框.这个QQ图标就可以被称作图形化的用户界面. 其实,用户界面的类型分为两类:Com ...
- Loadrunner之https协议录制回放报错如何解决?(九)
一.录制中遇到报错27778的问题(如下图1),即关于录制的链接为https开头的问题,分两个步骤解决,如下: 图1 https访问报错解决步骤如下: 1.修改Vuser-->Run-time ...