Educational Codeforces Round 72 (Rated for Div. 2)E(线段树,思维)

#define HAVE_STRUCT_TIMESPEC
#include<bits/stdc++.h>
using namespace std;
#define BUF_SIZE 100000
bool IOerror=0;//加了读入挂才1900ms+卡ddl过的,不加读入代码tleT_T
inline char nc(){
static char buf[BUF_SIZE], *p1=buf+BUF_SIZE, *pend=buf+BUF_SIZE;
if(p1==pend){
p1=buf;
pend=buf+fread(buf, 1, BUF_SIZE, stdin);
if(pend==p1){
IOerror=1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch){
return ch==‘ ‘||ch==‘\n‘||ch==‘\r‘||ch==‘\t‘;
}
inline void read(int &x){
char ch;
int sign=1;
while(blank(ch=nc()));
if(IOerror)return;
if(ch==‘-‘){
sign=-1;
ch=nc();
}
for(x=ch-‘0‘; (ch=nc())>=‘0‘&&ch<=‘9‘; x=x*10+ch-‘0‘);
x*=sign;
}
int a[200007];
typedef struct lst{
int l,r,mid;
int mn,mn2;
};
lst tree[15][800007];//建立十颗线段树,保存十进制上每一位每个位置的数字是多少,这个位置的数字在这一位为0就保存2e9
int tamp[7];
void up(int flag,int rt){
tamp[1]=tree[flag][rt<<1].mn;
tamp[2]=tree[flag][rt<<1].mn2;
tamp[3]=tree[flag][rt<<1|1].mn;
tamp[4]=tree[flag][rt<<1|1].mn2;
sort(tamp+1,tamp+5);//这里可能是运行速度慢的重要原因,sort比扫一遍大概慢一倍,即使如此还是比别人代码慢一倍T_T
tree[flag][rt].mn=tamp[1];
tree[flag][rt].mn2=tamp[2];
return ;
}
void build(int flag,int rt,int l,int r){
tree[flag][rt].l=l;
tree[flag][rt].r=r;
if(l==r){
int tmp=a[l]/pow(10,flag-1);
if(tmp%10==0)
tree[flag][rt].mn=tree[flag][rt].mn2=2e9;
else{
tree[flag][rt].mn=a[l];
tree[flag][rt].mn2=2e9;
}
return ;
}
int mid=tree[flag][rt].mid=l+r>>1;
build(flag,rt<<1,l,mid);
build(flag,rt<<1|1,mid+1,r);
up(flag,rt);
return ;
}
void update(int flag,int rt,int pos,int val){
if(tree[flag][rt].l==tree[flag][rt].r){
tree[flag][rt].mn=val;
tree[flag][rt].mn2=2e9;
return ;
}
if(pos<=tree[flag][rt].mid)
update(flag,rt<<1,pos,val);
else
update(flag,rt<<1|1,pos,val);
up(flag,rt);
}
pair<int,int>query(int flag,int rt,int l,int r){
if(tree[flag][rt].l>r&&tree[flag][rt].r<l)
return pair<int,int>(2e9,2e9);
if(tree[flag][rt].l>=l&&tree[flag][rt].r<=r)
return pair<int,int>(tree[flag][rt].mn,tree[flag][rt].mn2);
pair<int,int>tmp(2e9,2e9);
if(tree[flag][rt].mid>=l)
tmp=query(flag,rt<<1,l,r);
if(tree[flag][rt].mid<r){
pair<int,int>tp=query(flag,rt<<1|1,l,r);
tamp[1]=tp.first;
tamp[2]=tp.second;
tamp[3]=tmp.first;
tamp[4]=tmp.second;
sort(tamp+1,tamp+5);//又比扫一遍慢。。。
tmp={tamp[1],tamp[2]};
}
return tmp;
}
int main(){
int n,m;
read(n),read(m);
for(int i=1;i<=n;++i)
read(a[i]);
for(int i=1;i<=10;++i)
build(i,1,1,n);
for(int i=1;i<=m;++i){
int x,y,z;
read(x),read(y),read(z);
if(x==1)
for(int j=1;j<=10;++j){
int tmp=z/pow(10,j-1);
if(tmp%10)
update(j,1,y,z);//这一位上数字不为零就更新,将这一位变成z
else
update(j,1,y,2e9);//这一位上数字为零就更新,将这一位变成2e9
}
else{
long long mx=2e18;
for(int j=1;j<=10;++j){
pair<int,int>pr=query(j,1,y,z);
if(pr.second==2e9)
continue;//y~z区间内j这一位上没有两个数都不为0的
else
mx=min(mx,1ll*pr.first+1ll*pr.second);//y~z区间内j这一位上有两个数都不为0的,更新答案是否变成最小的两个数的和
}
if(mx==2e18)
cout<<-1<<"\n";
else
cout<<mx<<"\n";
}
}
return 0;
}

原文地址:https://www.cnblogs.com/ldudxy/p/11518201.html

时间: 2024-10-08 11:24:07

Educational Codeforces Round 72 (Rated for Div. 2)E(线段树,思维)的相关文章

Educational Codeforces Round 61 (Rated for Div. 2) G(线段树,单调栈)

#include<bits/stdc++.h>using namespace std;int st[1000007];int top;int s[1000007],t[1000007];int mx[4000007];int sum[4000007];int head[1000007],to[2000007],nex[2000007];int n,k;int a[10000077];int dfn;int tot;void pushup(int rt){    mx[rt]=max(mx[rt

Educational Codeforces Round 72 (Rated for Div. 2)-D. Coloring Edges-拓扑排序

Educational Codeforces Round 72 (Rated for Div. 2)-D. Coloring Edges-拓扑排序 [Problem Description] ? 给你一个有向图,给用最少的颜色给每条边染色,要保证不存在一个环中的所有边都是同一个颜色. [Solution] ? 用拓扑排序判断图中是否存在环,若图中不存在环,则所有边都是同一种颜色.否则,同一个环中,只要用两种颜色就可以满足题目条件,所以总的颜色数就是两种,对于一个环,一定会存在两种边:1.节点号小

Educational Codeforces Round 72 (Rated for Div. 2)E. Sum Queries?(线段树区间合并)

https://codeforc.es/contest/1217/problem/E 建立9棵数位线段树维护区间最小值和次小值,建议用struct建树方便进行区间合并 1 #define bug(x) cout<<#x<<" is "<<x<<endl 2 #define IO std::ios::sync_with_stdio(0) 3 #include <bits/stdc++.h> 4 #define iter ::it

Educational Codeforces Round 72 (Rated for Div. 2)

又垫底了. 和上一场一样,因为 D 题写错了一个小地方,把时间全部耗在上面了. (还不是水平问题,要是能想到 D 题的最优解法,也就不存在这种问题了. A. Creating a Character \[ str + x > int + epx - x \] \[ 2x>int+epx-str \] #include<bits/stdc++.h> #define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne,

Educational Codeforces Round 80 (Rated for Div. 2)E(树状数组,模拟,思维)

1 #define HAVE_STRUCT_TIMESPEC 2 #include<bits/stdc++.h> 3 using namespace std; 4 int mn[600007],mx[600007],a[600007],pos[600007],sum[600007]; 5 int n,m; 6 int lowbit(int x){ 7 return x&(-x); 8 } 9 void add(int x,int val){//单点更新 10 while(x<60

Educational Codeforces Round 36 (Rated for Div. 2)

Educational Codeforces Round 36 (Rated for Div. 2) F. Imbalance Value of a Tree You are given a tree T consisting of n vertices. A number is written on each vertex; the number written on vertex i is ai. Let's denote the function I(x,?y) as the differ

Educational Codeforces Round 69 (Rated for Div. 2) B - Pillars

Educational Codeforces Round 69 (Rated for Div. 2) B - Pillars There are n pillars aligned in a row and numbered from 1 to n. Initially each pillar contains exactly one disk. The i-th pillar contains a disk having radius ai. You can move these disks

Educational Codeforces Round 71 (Rated for Div. 2) D - Number Of Permutations

原文链接:https://www.cnblogs.com/xwl3109377858/p/11405773.html Educational Codeforces Round 71 (Rated for Div. 2) D - Number Of Permutations You are given a sequence of n pairs of integers: (a1,b1),(a2,b2),…,(an,bn). This sequence is called bad if it is

Educational Codeforces Round 36 (Rated for Div. 2) 题解

Educational Codeforces Round 36 (Rated for Div. 2) 题目的质量很不错(不看题解做不出来,笑 Codeforces 920C 题意 给定一个\(1\)到\(n\)组成的数组,只可以交换某些相邻的位置,问是否可以将数组调整为升序的 解题思路 首先如果每个数都能通过交换到它应该到的位置,那么就可以调整为升序的. 但实际上交换是对称的,如果应该在的位置在当前位置前方的数都交换完成,那么整体就是排好序的,因为不可能所有不在相应位置的数都在相应位置的后方.