屎,我写了半个小时5000多字,503给我变成1500了。但是也算我自己记录了一遍,反正我也不会再看()
牛牛多校9
我开了签到题2但是卡住了,还有跟着佬混了一下第三题(两个小时就干了这点)
签到2 Kill The Monsters:
想了很多贡献贪心和二分,最后答案是类似暴力
直接优先队列每一个大的数然后统计累计值和现在开始全部aoe的加和,但是要注意可能在100 100 100的情况下最后面的tmp才是正确答案,也就是一次aoe不用(这个我忘记了或者说我根本没有这种意识)
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int A[N];
int main()
{
int n,k;
cin >> n >> k;
priority_queue<int> q;
int max_v=0;
for(int i=1;i<=n;i++)
{
cin >> A[i];
max_v=max(max_v,A[i]);
q.push(A[i]);
}
if(k==1) {
cout << max_v << endl;
return 0;
}
int ans=0x3f3f3f3f;
int tmp=0;
while(!q.empty()) {
int t=q.top();
q.pop();
ans=min(tmp+t,ans);
if(t/k!=0) q.push(t/k);
tmp++;
}
cout << min(ans,tmp) << endl;
return 0;
}
2难.
贪心找可行复杂度解,题目比较模糊。类似数位dp的统计方式,找到边界的sqrt来确定边界,但是因为60位n的关系,要么用高精度,要么python,要么int128,大佬写的128,我需要后续自己琢磨一下,但是思路理解。
#include <iostream>
#include <algorithm>
using namespace std;
#define int long long
int n;
string L, R;
int m_sqrt(__int128 x)
{
int l = 0, r = 1e16;
while (l < r)
{
__int128 mid = l + r + 1 >> 1;
if (mid * mid <= x)
l = mid;
else
r = mid - 1;
}
return r + 1;
}
__int128 get_sum(__int128 x, __int128 y)
{
__int128 ls = m_sqrt(x), rs = m_sqrt(y);
return ls * rs;
}
__int128 to_128(string s)
{
__int128 x = 0;
for (int i = 0; i < s.size(); i++)
x = x * 10 + (s[i] - '0');
return x;
}
__int128 solve(string &s)
{
string l = s.substr(0, s.size() / 2), r = s.substr(s.size() / 2);
string lim;
while (lim.size() < s.size() / 2)
lim += '9';
__int128 limit = to_128(lim);
__int128 lv = to_128(l);
__int128 rv = to_128(r);
__int128 res = 0;
if (lv != 0)
res += get_sum(lv - 1, limit);
__int128 mid = m_sqrt(lv) - 1;
if (mid * mid == lv)
res += get_sum(0, rv);
return res;
}
void print(__int128 x)
{
string res;
while (x)
res += (x % 10 + '0'), x /= 10;
reverse(res.begin(), res.end());
if (!res.size())
res = "0";
cout << res << endl;
}
void del_1(string &s)
{
for (int i = s.size() - 1; ~i; i--)
if (s[i] == '0')
s[i] = '9';
else
{
s[i]--;
break;
}
}
signed main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n >> L >> R, del_1(L), print(solve(R) - solve(L));
}
这下面是重写的,所以随便口胡一下凌晨两点睡觉了:
round776
a,送
#include <bits/stdc++.h>
using namespace std;
void solve()
{
string s;
char c;
cin >> s >> c;
for(int i=0;i<s.size();i++) {
if(s[i]==c) {
if(i%2==0 && (s.size()-i-1)%2==0) {
cout << "YES" << endl;
return;
}
}
}
cout << "NO" << endl;
return;
}
int main()
{
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
b,敏感度不够,要么公式前面最大,要么后面的构造a-1最大
#include <bits/stdc++.h>
using namespace std;
void solve()
{
int l,r,a;
cin >> l >> r >> a;
int ans=r/a+r%a;
int max_v=r/a*a-1;
if(max_v>=l) ans=max(ans,max_v/a+max_v%a);
cout << ans << endl;
return;
}
int main()
{
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
c. 主要是得要知道一堆排列只要我想,我就可以构造出一种
不重叠的排序方式,所以只要确定了排列我就确定了ans值,所以
我就排序找到排列的最小ans值和就好了
然后对于这些数再单独排序输出前一个后一个
#include <bits/stdc++.h>
using namespace std;
#define x first
#define y second
typedef pair<int,int> PII;
typedef pair<int,pair<int,int>> PIII;
const int N=2e5+10;
bool cmp(const PIII &a,const PIII &b) {
if(a.y.y!=b.y.y) {
return a.y.y<b.y.y;
}
return false;
}
bool cmp2(const PIII &a,const PIII &b) {
if(a.y.x!=b.y.x) {
return a.y.x<b.y.x;
}
return false;
}
void solve()
{
vector<PIII> A;
int n,m;
cin >> n >> m;
for(int i=1;i<=m;i++) {
int x,w;
cin >> x >> w;
A.push_back({i,{x,w}});
}
sort(A.begin(),A.end(),cmp);
vector<PIII> B;
int sum=0;
for(int i=0;i<2*n;i++) {
sum+=A[i].y.y;
B.push_back(A[i]);
}
sort(B.begin(),B.end(),cmp2);
cout << sum << endl;
for(int i=0;i<n;i++) {
cout << B[i].x << " " << B[2*n-i-1].x << endl;
}
cout << endl;
return;
}
int main()
{
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
3.round966(div3)
a.错了一次没有处理n<3
#include <bits/stdc++.h>
using namespace std;
void solve()
{
int a;
cin >> a;
string s=to_string(a);
if(s[0]=='1' && s[1]=='0') {
if(s.size()<3) {
cout << "NO" << endl;
return;
}
if(s[2]=='0' || (s[2]=='1' && s.size()==3)) {
cout << "NO" << endl;
return;
}
}else {
cout << "NO" << endl;
return;
}
cout << "YES" << endl;
return;
}
int main()
{
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
b.错了一次没有处理!flag
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int A[N];
bool st[N];
void solve()
{
memset(st,0,sizeof st);
int n;
cin >> n;
bool flag=false;
for(int i=1;i<=n;i++)
{
cin >> A[i];
if(i!=1 && (st[A[i]-1]==false && st[A[i]+1]==false) && !flag) {
flag=true;
cout << "NO" << endl;
}
st[A[i]]=true;
}
if(!flag) cout << "YES" << endl;
return;
}
int main()
{
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
c.错了一次没有考虑n!=size直接错
<1>首先size=n
<2>map存值,st记录有没有遍历,找所有关联的看是否相同,然后下一个
问题出现了,没有考虑反向相同的问题
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int A[N];
bool st[N];
void solve()
{
int n;
cin >> n;
map<int,vector<int>> Hash;
for(int i=0;i<n;i++) {
cin >> A[i];
Hash[A[i]].push_back(i);
}
int m;
cin >> m;
while(m--) {
memset(st,0,sizeof st);
map<char,bool> judge;
string s;
cin >> s;
if(s.size()!=n) {
cout << "NO" << endl;
// cout << "HELLO" << endl;
continue;
}
bool flag=false;
for(int i=0;i<s.size();i++) {
if(st[i]) continue;
if(judge[s[i]] && !flag) {
cout << "NO" << endl;
flag=true;
break;
}
auto tt=Hash[A[i]];
judge[s[i]]=true;
for(int j=0;j<tt.size();j++) {
int tmp=tt[j];
st[tmp]=true;
if(s[i]!=s[tmp] && !flag) {
cout << "NO" << endl;
flag=true;
break;
}
}
if(flag) break;
}
if(!flag) cout << "YES" << endl;
}
return;
}
int main()
{
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
d.
每个L和R只能用一次但是不是区间只能一次,
LRLLR
LRLLRLLLLLR
12345
LRLLR 15 如果 3+12=15
我要尽可能找大的,因为找旁边的我不能往左必然更小
左边找L,右指针找R知道l=r
前缀和双指针扫一次
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+10;
int A[N],S[N];
void solve()
{
int n;
cin >> n;
for(int i=1;i<=n;i++) {
cin >> A[i];
S[i]=S[i-1]+A[i];
}
string s;
cin >> s;
int len=s.size();
int l=0,r=s.size()-1;
int ans=0;
while(l<r) {
if(s[l]!='L') l++;
if(s[r]!='R') r--;
if(s[l]=='L' && s[r]=='R') {
ans+=S[r+1]-S[l];
l++,r--;
}
}
cout << ans << endl;
return;
}
signed main()
{
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
e.
题目描述抽象,二位差分+排序乘积算贡献
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+10;
int n,m,k;
// void insert(int x1,int y1,int x2,int y2,int c,vector<vector<int>> &b){
// b[x1][y1]+=c;
// b[x2+1][y1]-=c;
// b[x2+1][y2+1]+=c;
// b[x1][y2+1]-=c;
// for(int i=1;i<=n;i++){
// for(int j=1;j<=m;j++){
// b[i][j]+=b[i-1][j]+b[i][j-1]-b[i-1][j-1];
// printf("%d ",b[i][j]);
// }
// printf("\n");
// }
// cout << endl;
// }
void solve()
{
cin >> n >> m >> k;
vector<vector<int>> b(n+5,vector<int> (m+5));
// b[0][0]=3;
// cout << b[0][0] << endl;
for(int i=1;i+k-1<=n;i++) {
for(int j=1;j+k-1<=m;j++) {
int x1=i,y1=j,x2=i+k-1,y2=j+k-1;
// insert(x1,y1,x2,y2,1,b);
b[x1][y1]+=1;
b[x2+1][y1]-=1;
b[x2+1][y2+1]+=1;
b[x1][y2+1]-=1;
}
}
vector<int> q,xing;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
b[i][j]+=b[i-1][j]+b[i][j-1]-b[i-1][j-1];
q.push_back(b[i][j]);
// printf("%d ",b[i][j]);
}
}
sort(q.begin(),q.end(),greater<int>());
int m;
cin >> m;
for(int i=1;i<=m;i++) {
int t;
cin >> t;
xing.push_back(t);
}
sort(xing.begin(),xing.end(),greater<int>());
// cout << "down" << endl;
long long ans=0;
for(int i=0;i<xing.size() && i<q.size();i++) {
ans+=xing[i]*q[i];
}
// cout << "down" << endl;
cout << ans << endl;
return;
}
signed main()
{
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
f.没写出来
好像是背包,明天补