8.19一点凌晨睡不着 就想着来做点事 思来想去不如来写题算了 杭电多校和牛客竞赛的题还没补 来一边写一边补七夕场的题
A题是一个二次元喂狗粮的问题就不写了┭┮﹏┭┮
C题是一个开玩笑的题hh
E是一个推理的也不写了0.0
D-亲密数:
这道题有个收获的地方就是求因子和:
LL find(LL x)
{
int sum = 1, t = sqrt(x);
for (int i = 2; i <= t; ++i)
if (x % i == 0)
sum += i + x / i;
if (t * t == x)
sum -= t;
return sum;
}
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define LL long long
LL find(LL x)
{
int sum = 1, t = sqrt(x);
for (int i = 2; i <= t; ++i)
if (x % i == 0)
sum += i + x / i;
if (t * t == x)
sum -= t;
return sum;
}
int main(){
LL l,r;
cin>>l>>r;
for(LL i=l;i<=r;i++){
LL x=find(i);
LL y=find(x);
if(i==y && y<x && x<=r){
cout<<y<<" "<<x<<endl;
return 0;
}
}
cout<<"-1"<<endl;
return 0;
}
G-ORMAX:
思路:容易知道|运算的结果是单调递增的,所以说求[l,r]里面所有数的|运算的结果就行
AC代码:
#include<iostream>
#define LL long long
using namespace std;
const LL mod = 998244353;
const int N = 1000001;
int a[N];
int T, n, q, ans;
struct SegmentTree1 {
int l, r, sum, la, tg;
#define ls x<<1
#define rs x<<1|1
#define l(x) tree[x].l
#define r(x) tree[x].r
#define sum(x) tree[x].sum
#define la(x) tree[x].la
#define tg(x) tree[x].tg
}tree[N << 2];
void pushdown(int x,int val) {
sum(x)=val;
tg(x)=val;
}
void pushup(int x){
sum(x)=sum(ls)|sum(rs);
}
void build(int x,int l,int r) {
la(x) = 1, tg(x) = 0;
l(x)=l,r(x)=r;
if (l(x) == r(x)) {
sum(x)=a[l];
return;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
pushup(x);
}
void query(int x, int l, int r) {
if (l <= l(x) && r >= r(x)) {
ans|=sum(x);
return;
}
if(tg(x)){
pushdown(ls,tg(x));
pushdown(rs,tg(x));
tg(x)=0;
}
int mid = (l(x) + r(x)) >> 1;
if (l <= mid)query(ls, l, r);
if (r > mid)query(rs, l, r);
return;
}
void up1(int x, int l, int r,int k) {
if (l<=l(x)&&r>=r(x)) {
sum(x)=k;
tg(x)=k;
return;
}
if(tg(x)){
pushdown(ls,tg(x)),pushdown(rs,tg(x));
tg(x)=0;
}
int mid = (l(x) + r(x)) >> 1;
if (l <= mid)up1(ls, l, r,k);
if (r > mid)up1(rs, l, r,k);
pushup(x);
}
int main() {
int m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
build(1,1,n);
for(int i=0;i<m;i++){
int op,l,r;
scanf("%d%d%d",&op,&l,&r);
if(op==1){
ans=0;
query(1,l,r);
printf("%d\n",ans);
}
else {
int nnum;
scanf("%d",&nnum);
up1(1,l,r,nnum);
}
}
return 0;
}
B题-发糖果
思路:把一个数字转换为X进制那么转换后如果是答案要求的‘整数’的话,那么这个数不断去除X剩下的要小于X,即:
bool check(int n,int i){
while(n%i==0)n/=i;
if(n<i)return true;//剩下的数要小于进制
return false;
}
易知:一个数字要是’整数’那么后面就要有0,即那个数字一定必须能被进制整除
即:
if(n%i==0){
if(check(n,i)){
ans=min(ans,i);
}
if(check(n,n/i)){
ans=min(ans,n/i);
}
}
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define LL long long
bool check(int n,int i){
while(n%i==0)n/=i;
if(n<i)return true;
return false;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
int n,ans;
scanf("%d",&n);
ans=n;
for(int i=2;i*i<=n;i++){
if(n%i==0){
if(check(n,i)){
ans=min(ans,i);
}
if(check(n,n/i)){
ans=min(ans,n/i);
}
}
}
printf("%d\n",ans);
}
return 0;
}
H题-牛妹的七夕闯关
思路:一个模拟题
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 1e5+10;
struct Node{
int p,a,b;
bool operator<(const Node& q)const{
return p<q.p;
}
}node[N];
int main(){
int n,m;
int ans=0;
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++){
scanf("%d%d%d",&node[i]. p,&node[i].a,&node[i].b);
}
sort(node,node+m);
ans=node[0].p;
ans+=max(node[0].a-ans%(node[0].a+node[0].b),0);
for(int i=1;i<m;i++){
ans+=node[i].p-node[i-1].p;
ans+=max(node[i].a-ans%(node[i].a+node[i].b),0);
}
if(node[m-1].p<n)ans+=n-node[m-1].p;
printf("%lld\n",ans);
return 0;
}
I-永远在一起
一个字符串字串的问题,dp的思想(可以类比LCS这种).
自己写的时候WA了很多次,后来看大佬的代码才明白哪里错了
思路:
从后往前遍历,如果说当前字符是W的话那么他后面必须是F,即当前的数量等于F的数量才能继承下去,如果说后面的字符是0的话那么他当前数量也是0,如果说后面是F的话,且F后面是WFWF这种那么当前数量就要加上WFWF的数量(即4种),即当前数量为4+1=5种,如WFWF=4,WFWFWF=9.
AC代码如下:
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 1e5+10;
char s[200500];
int len[200500][2];
int main(void)
{
scanf("%s",s);
int n=strlen(s),ans=0;
for (int i=n-1;i>=0;i--)
{
if (s[i]=='W'||s[i]=='?') len[i][0]=len[i+1][1]+1;
if (s[i]=='F'||s[i]=='?') len[i][1]=len[i+1][0]+1;
int d=max(len[i][0],len[i][1]);
ans+=d/2;
}
printf("%d\n",ans);
return 0;
}
F过的人很少我就不补了 免得折磨自己嘿嘿
补完题一看时间已经3点半了呜呜