1.操作格子
有n个格子,从左到右放成一排,编号为1-n。
共有m次操作,有3种操作类型:
1.修改一个格子的权值,
2.求连续一段格子权值和,
3.求连续一段格子的最大值。
对于每个2、3操作输出你所求出的结果。
样例输入
4 3
1 2 3 4
2 1 3
1 4 3
3 1 4
样例输出
6
3
#include<bits/stdc++.h>
using namespace std;
int n,m;
int sum,ans;
int ac[200007];
struct node{
int l,r,w;
}t[2000007],t2[2000007];
void build(int k,int l,int r){
t[k].l=l;
t[k].r=r;
t2[k].l=l;
t2[k].r=r;
if(l==r) t[k].w=ac[l],t2[k].w=ac[l];
else {
int mid=(l+r)/2;
build(k*2,l,mid);
build(k*2+1,mid+1,r);
t[k].w=max(t[k*2].w,t[2*k+1].w);
t2[k].w=t2[k*2].w+t2[2*k+1].w;
}
}
void query(int x,int y,int k){
if(x<=t[k].l && y>=t[k].r){
sum=max(sum,t[k].w);
}
else {
int mid=(t[k].l+t[k].r)/2;
if(x>=mid+1) query(x,y,2*k+1);
else if(y<=mid) query(x,y,k*2);
else {
query(x,y,k*2);
query(x,y,k*2+1);
}
}
}
void query2(int x,int y,int k){
if(x<=t[k].l && y>=t[k].r){
ans+=t2[k].w;
}
else {
int mid=(t2[k].l+t2[k].r)/2;
if(x>=mid+1) query2(x,y,2*k+1);
else if(y<=mid) query2(x,y,k*2);
else {
query2(x,y,k*2);
query2(x,y,k*2+1);
}
}
}
void update(int x,int y,int k){
if(t[k].l==t[k].r) {
t[k].w=y;
t2[k].w=y;
return ;
}
int m=(t[k].l+t[k].r)/2;
if(x>m) update(x,y,k*2+1);
if(x<=m) update(x,y,k*2);
t[k].w=max(t[k*2].w,t[2*k+1].w);
t2[k].w=t2[k*2].w+t2[k*2+1].w;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
{
scanf("%d",&ac[i]);
}
build(1,1,n);
int a,b;
while(m--){
char ss;
cin>>ss;
if(ss=='3'){
cin>>a>>b;
sum=0;
query(a,b,1);
printf("%d\n",sum);
}
else if(ss=='1'){
cin>>a>>b;
update(a,b,1);
}
else {
cin>>a>>b;
ans=0;
query2(a,b,1);
printf("%d\n",ans);
}
}
}
2.SPFA
输入格式
第一行输入n,m;第二行输入begin,end
接下来m行输入x,y,z;
n表示点数,m表示边数,begin表示起始点,end表示目标点,x、y表示连同连点z表示权值
输出格式
输出begin到end的最短路
样例输入
7 12
1 7
1 7 10
1 2 1
1 3 2
2 7 8
2 3 1
2 4 4
2 5 1
2 6 10
3 4 3
5 6 1
5 4 7
6 7 1
样例输出
4
#include<bits/stdc++.h>
using namespace std;
const int N = 100107;
const int M = 400107;
int n, m,begin,end;
int head[N], nex[M], to[M], val[M], ce;
void add(int u, int v, int w) {
to[++ce] = u; nex[ce] = head[v]; head[v] = ce; val[ce] = w;
to[++ce] = v; nex[ce] = head[u]; head[u] = ce; val[ce] = w;
}
int d[N];
bool used[N];
queue<int> q;
void spfa(int s) {
memset(d, 0x3f, sizeof d);
d[s] = 0;
q.push(s);
used[s] = true;
while(!q.empty()) {
int u = q.front(); q.pop();
used[u] = false;
for(int i=head[u]; i; i=nex[i]) {
int v = to[i], w = val[i];
if(d[u] + w < d[v]) {
d[v] = d[u] + w;
if(!used[v]) {
used[v] = true;
q.push(v);
}
}
}
}
}
int main(){
cin>>n>>m>>begin>>end;
for(int i=0;i<m;i++){
int u,v,w;
cin>>u>>v>>w;
add(u,v,w);
}
spfa(begin);
printf("%d\n", d[end]);
return 0;
}