首页 > 编程语言 >牛客 2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛 签到题13题

牛客 2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛 签到题13题

时间:2023-03-13 22:37:36浏览次数:47  
标签:13 return 签到 LL cin sgt 牛客 int maxn


题号 标题 已通过代码 通过率 我的状态
A A+B Problem 点击查看 1705/4843 通过, (贪心
B Komorebi的数学课 点击查看 1372/5349 通过 (快速幂
C 次佛锅 点击查看 1070/5160 通过 (字符串STL
D Setsuna的K数列 点击查看 597/2425 通过 (二进制)di
E Wiki下象棋 点击查看 308/2312 通过(BFS最短路
F 黄金律法 点击查看 1286/3529 通过(排序不等式
G 天气预报 点击查看 184/2800 通过(前缀和,尺取法) die
H 叠硬币 点击查看 67/702 通过(背包dp,打印方案)die
I A+B Problem again 点击查看 27/512 通过(数据敏感,字典树)die
J 史东薇尔城 点击查看 461/4005 通过(Dijkstra板子
K 取模 点击查看 207/3545 通过(数论分块板子)die
L 剪绳子 点击查看 84/593 通过(STL集合二分)di
M 数硬币 点击查看 34/385 通过(线段树板子)di
N 截肢葛瑞克 点击查看 0/288 未通过
O 上海施工小学 点击查看 5/1817 未通过

1、A+B Problem

牛客 2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛 签到题13题_ci

  • 找到最大值和次大值,如果当前数字不是最大值就加最大值,不然就加次大值
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;
int a[maxn], f[maxn];
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n; cin>>n;
if(n==1){
int x; cin>>x; cout<<x;
return 0;
}
for(int i = 1; i <= n; i++){
cin>>a[i]; f[i] = a[i];
}
sort(f+1,f+n+1);
for(int i = 1; i <= n; i++){
if(a[i]!=f[n])cout<<a[i]+f[n]<<" ";
else cout<<a[i]+f[n-1]<<" ";
}
return 0;
}

2、Komorebi的数学课

牛客 2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛 签到题13题_i++_02

  • 显然是一个快速幂板子题
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;
LL pows(LL a, LL x, LL p){if(x==0)return 1; LL t = pows(a, x>>1,p);if(x%2==0)return t*t%p;return t*t%p*a%p;}
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
LL n; cin>>n;
cout<<pows(n,n,n+2);
return 0;
}

3、次佛锅

牛客 2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛 签到题13题_算法_03

  • 判断T次询问的字符串在第一行位置后面的数字。
  • stringsteam加到map里面,直接输出就行
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
string s; getline(cin,s);
stringstream ss(s);
map<string,int>ma;
int x;
while(ss>>s>>x){
ma[s]+=x;
}
int T; cin>>T;
while(T--){
cin>>s;
cout<<ma[s]<<"\n";
}
return 0;
}

4、Setsuna的K数列

牛客 2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛 签到题13题_ci_04

  • 一开始没想到一直不知道怎么暴力,后来自己想想就是一个进制枚举
  • 考虑3^0,3^1,3^2,3^3,,,3^n各自可以使用0次或1次,那么就是选或者不选的问题
  • 那么就是判断第n个数的二进制位是否是1,如果是1就加上对应的3^i即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL maxn = 1e7+10,mod=1e9+7;
LL pows(LL a, LL x, LL p){if(x==0)return 1; LL t = pows(a, x>>1,p);if(x%2==0)return t*t%p;return t*t%p*a%p;}
int a[maxn];
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
LL n, k; cin>>n>>k;
LL w = n, ans = 0, t = 1;
while(w){
if(w&1){
ans = (ans+t)%mod;
}
t = t*k%mod;
w >>= 1;
}
cout<<ans<<"\n";
return 0;
}

5、Wiki下象棋

牛客 2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛 签到题13题_ci_05

  • 给出两种走位方式,分别求起点到终点的最短路
  • 直接bfs暴力即可
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL pows(LL a, LL x, LL p){if(x==0)return 1; LL t = pows(a, x>>1,p);if(x%2==0)return t*t%p;return t*t%p*a%p;}
int a[310][310];

struct node{int x, y,st=0;};
int vis[310][310];
int n, m;
int k, sx,sy, ex, ey;
int dx[] = {-2,-2,2,2,-1,1,-1,1};
int dy[] = {1,-1,1,-1,-2,-2,2,2};
int bfs(int ok){
memset(vis,0,sizeof(vis));
queue<node>q;
q.push({sx,sy,0});
while(q.size()){
node t = q.front(); q.pop();
if(t.x==ex&&t.y==ey){
return t.st;
}
for(int i = 0; i < 8; i++){
int nx = t.x+dx[i], ny = t.y+dy[i];
if(nx<1||nx>n||ny<1||ny>m)continue;
if(a[nx][ny])continue;
if(vis[nx][ny])continue;
if(ok==1){
if(abs(dx[i])==2){
if(a[t.x+dx[i]/2][t.y]==1){///||a[t.x+dx[i]][t.y]==1
continue;
}
}else{
if(a[t.x][t.y+dy[i]/2]==1){//||a[t.x][t.y+dy[i]]==1
continue;
}
}
}
q.push({nx,ny,t.st+1});
vis[nx][ny] = 1;
}
}
return -1;
}

int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int T; cin>>T;
while(T--){
cin>>n>>m;
cin>>k>>sx>>sy>>ex>>ey;
memset(a,0,sizeof(a));
for(int i = 1; i <= k; i++){
int tx, ty; cin>>tx>>ty;
a[tx][ty] = 1;
}
cout<<bfs(0)<<" "<<bfs(1)<<"\n";
}
return 0;
}

6、黄金律法

牛客 2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛 签到题13题_i++_06

  • 给出两个长度相同的序列,分别重新排序后,令每个对应位置上的数两两相乘加起来的值最小,求结果,ai<1e5。
  • 贪心,排序不等式结论,一个从大到小一个从小到大即可,注意不开ll只有10分
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e7+10;
LL a[maxn], b[maxn];
bool cmp(LL x, LL y){
return x>y;
}
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int T; cin>>T;
while(T--){
int n; cin>>n;
for(int i = 1; i <= n; i++)cin>>a[i];
for(int i = 1; i <= n; i++)cin>>b[i];
sort(a+1,a+n+1);
sort(b+1,b+n+1,cmp);
LL sum = 0;
for(int i = 1; i <= n; i++){
sum += a[i]*b[i];
}
cout<<sum<<"\n";
}
return 0;
}

7、天气预报

牛客 2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛 签到题13题_贪心_07

  • 将01串存为数组,即判断一个区间的区间和>=b,且长度>=a+b时满足条件,求区间个数。
  • 想到了前缀和O1求区间和,但是不知道为啥前缀和写错了(bushi),然后按照双指针每次枚举终点,k从前往后直到刚好不能满足条件为止(尺取法),那么以i为终点的区间个数就是k-1个,即包含区间[k,i]并向前面可以拓展k-1个。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e6+10;
LL c[maxn], s[maxn], sb[maxn];
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n; cin>>n;
LL a, b; cin>>a>>b;
string str; cin>>str;
LL ans = 0, k = 1;
for(int i = 1; i <= n; i++){
// c[i] = str[i-1]-'0'; //93%WA
// s[i] = s[i-1]+c[i]; //在家
// sb[i] = i-s[i]; //出门
if(str[i-1]=='0')s[i]=s[i-1], sb[i]=sb[i-1]+1;
else s[i]=s[i-1]+1, sb[i]=sb[i-1];
while(sb[i]-sb[k-1]>=a && s[i]-s[k-1]>=b && k<=i)k++;
ans += k-1;
}
if(a==0 && b==0)ans++;
cout<<ans<<"\n";
return 0;
}

8、叠硬币

牛客 2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛 签到题13题_动态规划_08

  • n堆硬币,选择最少的数量叠起来刚好等于高度H,多种方案选字典序小的输出。
  • dfs暴力所有选择方案+剪枝剪掉大于H高度的子树,33分
  • 首先不难想到要堆数量尽可能小,那么先从大到小排个序。
  • 然后考虑每堆硬币选还是不选,最后高度为h,就是类似于01背包问题变种+打印方案。
    记f[i]表示拼成高度为i的硬币堆需要的最小长度,转移时尝试使用当前a[i]为所有h到a[i]的最小高度更新,取max(f[j-a[i]]+1,f[i]),初始值都为正无穷,f[0]=0。
  • 记p[j]=i表示高度为j时使用的点为i,循环打印即可
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 3030;
int a[maxn], f[maxn], p[maxn];
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n, h; cin>>n>>h;
for(int i = 1; i <= n; i++)cin>>a[i];
sort(a+1,a+n+1,[](int x, int y){return x>y;});
memset(f,0x3f,sizeof(f));
f[0] = 0;
for(int i = 1; i <= n; i++){
for(int j = h; j >= a[i]; j--){
if(f[j-a[i]]==f[h+1])continue;
if(f[j]>=f[j-a[i]]+1){//等于的时候也要更新,因为字典序最小,后面的更优
f[j] = f[j-a[i]]+1;
p[j] = i;
}
}
}
if(f[h]==f[h+1])return cout<<"-1\n", 0;
cout<<f[h]<<"\n";
while(h){
cout<<a[p[h]]<<" ";
h -= a[p[h]];
}
return 0;
}

9、A+B Problem again

牛客 2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛 签到题13题_贪心_09

  • 第一题的做法是直接每个数加上除了自己以外的最大值,最大值可以扫一遍O(n)获得且最大值是固定的不会变的,但是本题因为改变了两数比较的规则,所以对于每个数,最大值需要加的数可能会不一样,所以只能每次O(n)扫一遍去按照题目规则做加法,NM复杂度+手写字符串高精的常数只能拿到20分。
  • 考虑新的规则本身,注意到题目每个数字的大小都不超过6位,可以把每个数都拆出来逐位的考虑,即越靠前的位,两位相加就越大。所以能过的做法是把每个数都当做6位的字符串建一颗字典树(类似于暑假集训遇到的异或最大和的做法去比较)。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;

int a[maxn][9];
int tree[maxn*6][10], cnt;
vector<int>vc[maxn*6];
void insert(int x){
int p = 0; //根
for(int i = 6; i > 0; i--){ //靠前的位加到上层
if(!tree[p][a[x][i]])tree[p][a[x][i]]=++cnt;
p = tree[p][a[x][i]];
}
vc[p].push_back(x);//叶子节点存这里保存下标
}
int query(int p, int j, int i){
// cout<<"as: "<<p<<"\n";
if(j==0){
// cout<<p<<"\n";
for(int x:vc[p]){
if(x!=i)return x;//不能跟自己相加
}
return 0;
}
int st = 9-a[i][j];//最好是能凑到9
for(int k = 1; k <= 10; k++){
if(tree[p][st]){
int ans = query(tree[p][st],j-1,i);//去凑第i个数的下一位
if(ans)return ans;
}
st--; //凑不到就凑的小一点
if(st<0)st = 9;
}
return 0;
}

int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n; cin>>n;
for(int i = 1; i <= n; i++){
int x; cin>>x;
for(int j = 1; j <= 6; j++)a[i][j]=x%10, x/=10;//654321的顺序存进去
insert(i);
}
for(int i = 1; i <= n; i++){
int x = query(0,6,i), ans = 0;
for(int j = 6; j >= 1; j--)
ans = ans*10+(a[i][j]+a[x][j])%10;
cout<<ans<<" ";
}
return 0;
}

10、史东薇尔城

牛客 2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛 签到题13题_算法_10

  • 给出n个点m条边的无向图,求点s->1->t的最短路
  • Dijkstra板子跑出1到所有点的最短路,每次输出就行
#include<bits/stdc++.h>
#define lowbit(x) x&(-x)
#define debug(a) cout<<"debug:"<<#a<<"\n"
using namespace std;
typedef long long LL;
typedef pair<LL,LL>P;///first距离,second编号
const LL mod=1e9+7;
const LL maxn=1e5+1000;
struct Edge{
LL to,val;
};
vector<Edge>g1[maxn];
vector<Edge>g4[maxn];
multiset<LL>s1;
LL dis1c[maxn],disnd[maxn];
LL a[maxn];
LL n,m,q;
bool vis[maxn];
void dijkstra(LL st, vector<Edge>g[], LL dis[]){
memset(vis,0,sizeof(vis));
for(LL i=0;i<n+10;i++) dis[i]=1e18;
priority_queue< P,vector<P>, greater<P> >que;
dis[st]=0;
que.push({dis[st],st});
while(!que.empty()){
P now=que.top();que.pop();
LL u=now.second;
if(vis[u]) continue;
vis[u]=1;
for(LL i=0;i<g[u].size();i++){
LL v=g[u][i].to;
LL cost=g[u][i].val;
if(dis[v]>dis[u]+cost){
dis[v]=dis[u]+cost;
que.push({dis[v],v});
}
}
}
}
int main(void){
cin.tie(0);std::ios::sync_with_stdio(false);
cin>>n>>m;
for(LL i=1;i<=m;i++){
LL u,v,c;cin>>u>>v>>c;
g1[u].push_back({v,c});
g1[v].push_back({u,c});
}

dijkstra(1,g1,dis1c);
int T; cin>>T;
while(T--){
int s, t; cin>>s>>t;
cout<<dis1c[s]+dis1c[t]<<"\n";
}
return 0;
}

11、取模

牛客 2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛 签到题13题_算法_11

  • 数论分块板子题(buhui),51nod 1168 余数之和 原题简单版(cpp)
  • 注意取模没有取好只有60分。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod = 998244353;
LL pows(LL a, LL x, LL p){if(x==0)return 1; LL t = pows(a, x>>1,p);if(x%2==0)return t*t%p;return t*t%p*a%p;}
int main(){
LL n; cin>>n;
LL xx=pows(2LL,mod-2,mod);
LL ans=(n%mod)*(n%mod)%mod;
LL ret=sqrt(n);
LL tmp=n/(ret+1);
for(int i=1;i<=tmp;i++){
ans=(ans-n/i*i)%mod;
}
for(int i=n/(tmp+1);i>0;i--){
LL a=n/i; a %= mod;
LL b=n/(i+1)+1; b %= mod;
LL cnt=(((LL)i*((a+b))%mod)%mod*(a-b+1)%mod+mod)*xx%mod;
ans=(ans-cnt+mod)%mod;
}
cout<<(ans%mod+mod)%mod<<endl;
return 0;
}

12、剪绳子

牛客 2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛 签到题13题_算法_12

  • 每次减绳子的值用set维护一下让其有序,对于查询的长度,二分找到刚好比他大的和比他小的,两个减一下就是答案,边界0和10
  • 其实set维护以后暴力一下也可以过()
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int q; cin>>q;
set<float>se;
se.insert(0);
se.insert(10);
while(q--){
string op; float x; cin>>op>>x;
if(op=="C"){
se.insert(x);
}else{
auto p1=lower_bound(se.begin(),se.end(),x);
auto p2=upper_bound(se.begin(),se.end(),x);
if(p2==se.end())printf("%.5f\n",10-(*--p1));
else printf("%.5f\n",(*p2)-(*--p1));
}
}
return 0;
}

13、数硬币

牛客 2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛 签到题13题_i++_13

  • 给出长为n的序列,支持区间加值,区间和查询,区间gcd。n<1e5,q<1e5。
  • 线段树板子题。 可以参考Acwings246. 区间最大公约数
  • 讲个笑话,线段树调了两个小时拿了10分,发现循环一遍打暴力可以过。。。。
//暴力AC
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;
int a[maxn];
int main(){
int n, m; cin>>n>>m;
for(int i =1; i <= n; i++)cin>>a[i];
while(m--){
int op, l, r; cin>>op>>l>>r;
if(l>r)swap(l,r);
if(op==0){
int d; cin>>d;
for(int i = l; i <= r; i++)a[i]+=d;
}else if(op==1){
LL ans = 0;
for(int i = l; i <= r; i++)ans+=a[i];
cout<<ans<<"\n";
}else{
int ans = a[l];
for(int i = l+1; i <= r; i++)ans = gcd(ans, a[i]);
cout<<ans<<"\n";
}
}
return 0;
}
//10分代码,区间加的修改写错了,不知道错哪
//题面:线段树,支持区间+d,区间求gcd
//思路:gcd(a,b)=gcd(a,b−a),所以(a,b,c)=(a,b−a,c−b),即在知道a的情况下可以通过维护差分序列(b-a,c-b)的gcd来获得三个数的gcd,而差分数列可以变区间修改为单点修改
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;

LL a[maxn], b[maxn];

#define lch p<<1
#define rch p<<1|1
struct node{
int l, r; LL v, d, s;
}sgt[maxn<<2];
LL tag[maxn<<2];
void pushup(node &p, node &l, node &r){
p.v = l.v+r.v;
p.d = __gcd(l.d,r.d);
p.s = l.s+r.s;
}
void pushup(int p){ pushup(sgt[p],sgt[lch],sgt[rch]); }
void pushdown(int p){
if(tag[p]){
tag[lch] += tag[p]; tag[rch]+= tag[p];
sgt[lch].s += (sgt[lch].r-sgt[lch].l+1)*tag[p];
sgt[rch].s += (sgt[rch].r-sgt[rch].l+1)*tag[p];
tag[p] = 0;
}
}
void build(int p, int l, int r){
if(l==r)sgt[p] = {l,r,b[l],b[l],a[l]};
else{
sgt[p] = {l,r};
int mid = l+r>>1;
build(lch, l, mid);
build(rch, mid+1, r);
pushup(p);
}
}
LL query_d(int p, int l, int r){
if (l > r) return 0;//Segmentation Fault
if(sgt[p].l>=l && sgt[p].r<=r)return sgt[p].d;
else{
int mid = sgt[p].l+sgt[p].r>>1;
if(r<=mid)return query_d(lch, l, r);
else if(l>mid)return query_d(rch,l,r);
else return __gcd(query_d(lch,l,r),query_d(rch,l,r));
}
}
LL query_v(int p, int l, int r){
if (l > r) return 0;
if(sgt[p].l>=l && sgt[p].r<=r)return sgt[p].v;
else{
int mid = sgt[p].l+sgt[p].r>>1;
if(r<=mid)return query_v(lch, l, r);
else if(l>mid)return query_v(rch,l,r);
else return query_v(lch,l,r)+query_v(rch,l,r);
}
}
LL query_s(int p, int l, int r){
if (l > r) return 0;
if(sgt[p].l>=l && sgt[p].r<=r)return sgt[p].s;
else{
pushdown(p);
int mid = sgt[p].l+sgt[p].r>>1;
LL ans = 0;
if(l<=mid)ans += query_s(lch, l, r);
if(r>mid)ans += query_s(rch,l,r);
return ans;
}
}
void modify(int p, int x, LL v){
if(sgt[p].l==sgt[p].r && sgt[p].l==x){//找到位置
sgt[p].d += v; sgt[p].v+=v;
}else{
int mid = sgt[p].l+sgt[p].r>>1;
if(x<=mid)modify(lch,x,v);
else modify(rch, x, v);
pushup(p);
}
}
void modify_s(int p, int l, int r, LL v){
if(l <= sgt[p].l && sgt[p].r<=r){
tag[p] += v;
sgt[p].s += (sgt[p].r-sgt[p].l+1)*v;
}else{
pushdown(p);
int mid = sgt[p].l+sgt[p].r>>1;
if(l<=mid)modify_s(lch,l,r,v);
if(r>mid)modify_s(rch,l,r,v);
pushup(p);
}
}

int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n, m; cin>>n>>m;
for(int i = 1; i <= n; i++){
cin>>a[i]; b[i]=a[i]-a[i-1];
}
build(1,1,n+1);
for(int i = 1; i <= m; i++){
int op ; cin>>op;
if(op==0){
LL l, r, d; cin>>l>>r>>d;
if(l>r)swap(l,r);//?
modify_s(1,l,r,d);
modify(1, l, d);
//if(r+1<=n)
modify(1,r+1,-d);
}else if(op==2){
LL l, r; cin>>l>>r;
if(l>r)swap(l,r);//?
LL t = query_v(1,1,l);
cout<<abs( __gcd(t, query_d(1, l+1, r)))<<"\n";
}else if(op==1){
LL l, r; cin>>l>>r;
if(l>r)swap(l,r);//?
cout<<query_s(1,l,r)<<"\n";
// LL sum = 0;
// for(int i = l; i <= r; i++){
// sum += query_v(1,1,i);
// }
// cout<<sum<<"\n";
}
}
return 0;
}
//别人的一颗可以通过的线段树
#include <bits/stdc++.h>
typedef long long ll;
const int MAXN = 1e5 + 10;
ll _abs(ll x)
{
return x < 0? -x: x;
}
struct node
{
ll l, r, sum, gcd;
} tr[MAXN << 2];
ll tag[MAXN << 2], a[MAXN];
void pushup(int u)
{
tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
tr[u].gcd = std::__gcd(_abs(tr[u << 1].gcd), _abs(tr[u << 1 | 1].gcd));
}
void pushdown(int u)
{
if (tag[u])
{
tag[u << 1] += tag[u]; tag[u << 1 | 1] += tag[u];
tr[u << 1].sum += (tr[u << 1].r - tr[u << 1].l + 1) * tag[u];
tr[u << 1 | 1].sum += (tr[u << 1 | 1].r - tr[u << 1 | 1].l + 1) * tag[u];
tag[u] = 0;
}
}
void build(int l, int r, int u)
{
tr[u] = {l, r};
if (l == r)
{
tr[u].sum = a[l];
tr[u].gcd = a[l] - a[l - 1];
return;
}
int mid = l + r >> 1;
build(l, mid, u << 1); build(mid + 1, r, u << 1 | 1);
pushup(u);
}
void modifysum(int l, int r, int k, int u)
{
if (l <= tr[u].l && tr[u].r <= r)
{
tag[u] += k;
tr[u].sum += (tr[u].r - tr[u].l + 1) * k;
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) modifysum(l, r, k, u << 1);
if (r > mid) modifysum(l, r, k, u << 1 | 1);
pushup(u);
}
void modifygcd(int x, int k, int u)
{
if (tr[u].l == tr[u].r && tr[u].l == x)
{
tr[u].gcd += k;
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if (x <= mid) modifygcd(x, k, u << 1);
else modifygcd(x, k, u << 1 | 1);
pushup(u);
}
ll querysum(int l, int r, int u)
{
if (l <= tr[u].l && tr[u].r <= r)
return tr[u].sum;
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
ll ans = 0;
if (l <= mid) ans += querysum(l, r, u << 1);
if (r > mid) ans += querysum(l, r, u << 1 | 1);
return ans;
}
ll querygcd(int l, int r, int u)
{
if (l > r) return 0;
if (l <= tr[u].l && tr[u].r <= r)
return _abs(tr[u].gcd);
int mid = tr[u].l + tr[u].r >> 1;
ll gcd = 0;
if (l <= mid) gcd = std::__gcd(gcd, querygcd(l, r, u << 1));
if (r > mid) gcd = std::__gcd(gcd, querygcd(l, r, u << 1 | 1));
return gcd;
}
int main()
{
int n, q; scanf("%d%d", &n, &q);
for (int i = 1; i <= n; ++i)
scanf("%lld", &a[i]);
a[n + 1] = 0;
build(1, n + 1, 1);
while (q--)
{
int opt; scanf("%d", &opt);
if (opt == 0)
{
int x, y, k; scanf("%d%d%d", &x, &y, &k);
if (x > y) std::swap(x, y);
modifysum(x, y, k, 1);
modifygcd(x, k, 1); modifygcd(y + 1, -k, 1);
}
else if (opt == 1)
{
int x, y; scanf("%d%d", &x, &y);
if (x > y) std::swap(x, y);
printf("%lld\n", querysum(x, y, 1));
}
else
{
int x, y; scanf("%d%d", &x, &y);
if (x > y) std::swap(x, y);
printf("%lld\n", std::__gcd(querysum(x, x, 1), querygcd(x + 1, y, 1)));
}
}
// for (int i = 1; i <= n; ++i)
// printf("%lld ", querysum(i, i, 1));
// printf("%lld\n", querysum(6, 9, 1));
return 0;
}
/*
5 5
63 96 19 7 37
0 1 3 95
1 1 3
0 2 2 85
1 5 3
2 3 2

*/


标签:13,return,签到,LL,cin,sgt,牛客,int,maxn
From: https://blog.51cto.com/gwj1314/6115726

相关文章

  • 3.13每日总结——地铁查询系统1.0(第一次合作)
           思路首先是数据库存储:(1)采用List集合来存储线路上的站点信息。public static List lines = new ArrayList<>();(2)采用List集合来存储相邻站点信......
  • 每日总结-23.3.13
    课上内容地铁系统中的前两个查询部分//线路号查询,Stringname=线路名称publicPdchaxunxianlu(Stringname)throwsSQLException{Stringsql="s......
  • 3.13总结(结组)
    1,建立MySQL数据库并建立连接,再针对每一条线路以及换乘信息车站分别建立表。2,查询:制作查询界面,查询站点或线路的信息,并将其输出,并针对错误的输入报错。3,对于起点终点的查询,......
  • 3.13
    将北京地铁线路信息等用一个文本文件以subway.txt的形式保存起来,保存的信息包括地铁线路名称和拥有的站数、对应线路下的站点名称以及相邻站的距离,使得可以通过读取这个文......
  • 每日总结2023/3/13
    成对作业今天上课王老师让我们二人组队完成一个地铁线路查询网页项目。下面是我的思路:首先进行该有的线路分析,比如在那个线路转线和如何找到最优的路线。我们首先进行......
  • 2023.3.13每日总结
    <%@pagelanguage="java"contentType="text/html;charset=UTF-8"pageEncoding="UTF-8"%><%@pageimport="java.util.*"%><!DOCTYPEhtmlPUBLIC"-//W3C//DTD......
  • C/C++班级成绩管理系统[2023-03-13]
    C/C++班级成绩管理系统[2023-03-13]4.5班级成绩管理系统题目描述对一个有N个(>=10)学生的班级,每个学生有M门(>=5)课程。该系统实现对班级成绩的录入、显示、修改、排序......
  • 3月13日软工日报
    学习时间:6h代码:400行博客量:2学到的知识点:了解到了PendingIntent与AlarmManager其中PendingIntent是Intent的封装,但是不像Intent一样会立刻执行,需要达到某些条件才会进......
  • 3.13每日总结
    今天,建民老师给我们布置了第一次结对作业,让我们做一个地铁查询系统具体要求如下:1.1存储:线路号,车站唯一标识ID,线路的各个站名,车站的换乘信息等信息。1.2需要考虑:如何表示......
  • P4387 洛谷做题笔记 2023313
    P4387洛谷做题笔记2023/3/13这道题的关键点在于,在入栈的同时可以完成出栈操作,这就需要在每一次压入时检测是否出栈。这道题还有一个易错点,就是在每一次询问之后,还必须......