# 目录
L Zhang Fei Threading Needles - Thick with Fine
J Function
L Zhang Fei Threading Needles - Thick with Fine
签到题 输出x-1
# include <bits/stdc++.h> using namespace std; #define IOS ios::sync_with_stdio(false);cin.tie(0); #define endl '\n' int main() { IOS int n; cin>>n; cout<<n-1<<endl; }
A Drill Wood to Make Fire
签到题 一个判断就行
# include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0);
#define endl '\n'
int main()
{
IOS
int t;
cin>>t;
while(t--)
{
int n,s,v;
cin>>n>>s>>v;
if(s*v>=n)
{
cout<<"1"<<endl;
}
else
{
cout<<"0"<<endl;
}
}
}
K - Split
题目意思 给你一个单调非增序列 然后有俩个操作
第一个操作为 更改 ax to ax−1+ax+1−ax.
第二个操作是将这个序列分为k份,每份长度至少为一 序列的值为序列最大值减去最小值
求 分成K份后序列值最小
解题思路:先考率第二个操作
设当前序列长度为6;
首先如果K=2的时候 序列的值存在
a1-a3+a4-a6
a1-a4+a5-a6
a1-a2+a3-a6
........
如果 K=3的时候 序列的值存在
a1-a2+a3-a4+a5-a6
a1-a1+a2-a3+a4-a6
观察上面发现第二个操作等价与序列第一个值减去最后一个值选取前(k-1)个最小序列相邻俩个元素的差值
于是我们将预处理一下序列的之间相邻俩个元素的差值
这时候发现当我们执行第一个操作的时候
改变相邻元素的差值变为了
ax+1-ax
ax-ax-1
相邻元素差值并未改变
故操作一没有任何作用
# include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0);
#define endl '\n'
# define int long long
const int N=1e6+10;
int a[N];
int b[N];
int sum[N];
signed main()
{
IOS
int n;
cin>>n;
int cnt=0;
for(int i=1; i<=n; i++)
{
cin>>a[i];
}
for(int i=2;i<=n;i++)
{
b[i-1]=a[i]-a[i-1];
}
sort(b+1,b+n);
for(int i=1;i<n;i++)
{
sum[i]=sum[i-1]+b[i];
}
int q;
cin>>q;
while(q--)
{
int op;
int x;
cin>>op>>x;
if(op==1)
{
int res=0;
res=a[1]-a[n]+sum[x-1];
cout<<res<<endl;
}
}
}
J Function
题意:
先给你n个(x-i)*(x-i)+b的式子
然后有俩个操作
第一个操作 再给你一个(x-a)*(x-a)+b的式子
第二个操作 求上面中当x=a最小的值
a,b的范围都大于等于1小于等于n;
解题思路 当i=a的时候值为b
如果其他式子比这个小也就是(a-i)*(a-i)+c<b
(a-i)*(a-i)<b-c
由于 b c 的范围以给定
则可以求出i的范围为(a-sqrt(n),a+sqrt(n))
这样可以在log(n)的时间求出最小值
# include <bits/stdc++.h>
using namespace std;
# define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);
#define endl '\n'
const int N=1e5+10;
int a[N];
signed main()
{
IOS
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
int q;
cin>>q;
while(q--)
{
int op,x;
cin>>op;
if(op==0)
{
int y;
cin>>x>>y;
a[x]=min(a[x],y);
}
else
{
cin>>x;
int d=sqrt(1e5);
int res=1e18;
for(int i=max(1ll,x-d);i<=min(n,x+d);i++)
{
res=min((x-i)*(x-i)+a[i],res);
}
cout<<res<<endl;
}
}
}
I - Tree
题意给你一个树
然后有俩个操作
第一个操作将从点a到点b的边都异或w
第二个操作求连接点a所有边的异或和
发现第一个操作只会改变端点和末端点的答案
于是只用给点a和点b异或w就行了
# include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0);
#define endl '\n'
# define int long long
const int N=5*1e5+10;
int d[N];
signed main()
{
IOS
int n,q;
cin>>n>>q;
for(int i=1; i<=n-1; i++)
{
int x,y,w;
cin>>x>>y>>w;
d[x]^=w;
d[y]^=w;
}
while(q--)
{
int op;
int x,y,w;
cin>>op;
if(op==1)
{
cin>>x>>y>>w;
d[x]^=w;
d[y]^=w;
}
else
{
cin>>x;
cout<<d[x]<<endl;
}
}
}