BIT&spfa_081006day1

    又看了看,树状数组,明白了以前死背的的东西。关于离线算法有了初步的认识。另外,今天看了看spfa算法,这些的确都淡忘了。

BIT.pas_code:

var
  n,m,q,i,j,k,x1,y1,x2,y2:longint;
  c:array[1..1000,1..1000] of longint;
  z:char;

procedure modify(i,j,k:longint);
var temp:longint;
begin
  temp:=j;
  while i<=n do begin
    j:=temp;
    while j<=m do begin
      c[i,j]:=c[i,j]+k;
      inc(j,j and -j);
      end;
    inc(i,i and -i);
    end;
end;

function sum(i,j:longint):longint;
var temp,ans:longint;
begin
  temp:=j; ans:=0;
  while i>0 do begin
    j:=temp;
    while j>0 do begin
      ans:=ans+c[i,j];
      dec(j,j and -j);
      end;
    dec(i,i and -i);
    end;
  exit(ans);
end;

begin
  assign(input,'BIT.in'); reset(input);
  assign(output,'BIT.out'); rewrite(output);
  readln(n,m,q);
  for i:=1 to q do
    begin
    read(z);
    case z of
            'C':begin
                readln(x1,y1,k);
                modify(x1,y1,k);
                end;
            'Q':begin
                readln(x1,y1,x2,y2);
                writeln(sum(x2,y2)-sum(x1-1,y2)-sum(x2,y1-1)+sum(x1-1,y1-1));
                end;
            end;
    end;
  close(input); close(output);
end.


 

depressedJ.cpp_code:

#include<iostream>
using namespace std;
const int MXN=100010;
const int MXQ=400010;
struct opt{
	int t,q,n,x,y;
}w[MXQ];
int n,m,o,c[MXN];
void optinsert(int t,int q,int n,int x,int y) {
	w[o].t=t; w[o].q=q; w[o].n=n; w[o].x=x; w[o].y=y;
	o++;
}
bool cmp(const opt &a,const opt &b) {
	return (a.n<b.n || (a.n==b.n&&a.t<b.t));
}
bool cmp2(const opt &a,const opt &b) {
	return (a.t<b.t);
}
void modify(int i,int k) {
	while (i<=n) {
		c[i]+=k;
		i+=i&(-i);
	}
}
int search(int i) {
	int ans=0;
	while (i>0) {
		ans+=c[i];
		i-=i&(-i);
	}
	return(ans);
}
int main()
{
	int i,k,x,y,a[MXN];
	char st[3];
	freopen("depressedJ.in","r",stdin);
	freopen("depressedJ.out","w",stdout);	
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++) {
		scanf("%d",&a[i]);
		optinsert(0,0,a[i],i,0);
	}
	gets(st);
	for(i=1;i<=m;i++) {
		if (getchar()=='C') {
			scanf("%d%d",&x,&k);
			optinsert(i,1,a[x],x,0);
			optinsert(i,0,k,x,0);
			a[x]=k;
		}else {
			scanf("%d%d%d",&x,&y,&k);
			optinsert(i,2,k,x,y);
		}
		gets(st);
	}
	for(i=1;i<=n;i++) optinsert(m+1,1,a[i],i,0);
	sort(w,w+o,cmp);
	for(i=0;i<o;i++) 
		if (w[i].q==2) w[i].y=search(w[i].y)-search(w[i].x-1);
		else if (w[i].q==0) modify(w[i].x,1); else modify(w[i].x,-1);
	sort(w,w+o,cmp2);
	for(i=0;i<o;i++)
		if (w[i].q==2) printf("%d\n",w[i].y);
	return 0;
}

 

FloatingMedian.cpp_code:

#include<iostream>
#define NEXT(a) (((a)*mul+add)%M)
using namespace std;
const int M=65536;
int c[M+1];
void modify(int i,int k) {
	while (i<=M) {
		c[i]+=k;
		i+=i&-i;
	}
}
int find(int k) {
	int i,cnt=0,ans=0;
	for(i=16;i>=0;i--) {
		ans+=1<<i;
		if (ans>M||cnt+c[ans]>=k) ans-=1<<i;
		else cnt+=c[ans];
	}
	return ans+1;
}
int main()
{
	freopen("FloatingMedian.in","r",stdin);
	freopen("FloatingMedian.out","w",stdout);
    int seed,mul,add,n,k,i;
	cin>>seed>>mul>>add>>n>>k;
	int mid=(k+1)/2;
	unsigned long a=seed,b=seed;
	long long ans=0;
	for(i=1;i<=n;i++) {
		modify(a+1,1);
		a=NEXT(a);
		if (i>=k) {
			ans+=find(mid)-1;
			modify(b+1,-1);
			b=NEXT(b);
		}
	}
	cout<<ans<<endl;
	return 0;
}


turncard.cpp_code:

#include<iostream>
using namespace std;
const int MXN=100010;
int n,m;
bool c[MXN];
void modify(int i) {
	if (!i) return;
	while (i<=n) {
		c[i]=!c[i];
		i+=i&(-i);
	}
}
bool sum(int i) {
	bool ans=0;
	while (i>0) {
		ans^=c[i];
		i-=i&(-i);
	}
	return ans;
}
int main()
{
	int i,x,y;
	char st[3];
	freopen("turncard.in","r",stdin);
	freopen("turncard.out","w",stdout);
	scanf("%d%d",&n,&m);
	gets(st);
	for(i=1;i<=m;i++) {
		if (getchar()=='T') {
			scanf("%d%d",&x,&y);
			modify(y);
			modify(x-1);
		}else{
			scanf("%d",&x);
			if (sum(n)^sum(x-1)) puts("no"); else puts("yes");
		}
		gets(st);
	}
	return 0;
}


 


spfa.pas_code:

var
  a,b,e:array[1..1000] of longint;
  vis:array[1..2000] of boolean;
  q,d,f:array[1..2001] of longint;
  n,m,i,s,t:longint;
procedure qsort(l,r:longint);
  var i,j,x,y:longint;
  begin
    i:=l;
    j:=r;
    x:=a[(l+r) shr 1];
    repeat
      while a[i]<x do inc(i);
      while a[j]>x do dec(j);
      if not(i>j) then begin
        y:=a[i]; a[i]:=a[j]; a[j]:=y;
        y:=b[i]; b[i]:=b[j]; b[j]:=y;
        y:=e[i]; e[i]:=e[j]; e[j]:=y;
        inc(i);
        dec(j);
      end;
    until i>j;
    if i<r then qsort(i,r);
    if l<j then qsort(l,j);
  end;
procedure spfa(s:longint);
  var i,k,l,t:longint;
  begin
    fillchar(vis,sizeof(vis),0);
    for i:=1 to n do d[i]:=maxlongint;
    d[s]:=0;
    l:=0;
    t:=1;
    q[1]:=s;
    vis[s]:=true;
    repeat
      l:=l mod 10000 +1;
      k:=q[l];
      for i:=f[k] to f[k+1]-1 do
        if d[k]+e[i]<d[b[i]] then
          begin
            d[b[i]]:=d[k]+e[i];
            if not vis[b[i]] then begin
              t:=t mod 10000 +1;
              q[t]:=b[i];
              vis[b[i]]:=true;
            end;
        end;
      vis[k]:=false;
    until l=t;
  end;
Begin
  readln(n,m);
  for i:=1 to m do
    readln(a[i],b[i],e[i]);
  qsort(1,m);
  for i:=1 to m do
    if f[a[i]]=0 then f[a[i]]:=i;
  f[n+1]:=m+1;
  for i:=n downto 1 do
    if f[i]=0 then f[i]:=f[i+1];
  readln(s,t);
  spfa(s);
  writeln(d[t]);
end.


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值