2022/5/14

142 篇文章 0 订阅
142 篇文章 1 订阅

B - Stone Age Problem

一个操作是将a[i]换成x,另一个操作是都换成x,每次操作都要输出数组的和;

这题的麻烦点就在于第二个操作,这里我们可以用一下线段树的tag思想,也不完全像tag,只能说类似吧,设一个vis数组表示元素i进行过多少次第二种操作,cnt表示到目前为止进行了多少次操作,last表示上一个第二操作的x,如果vis[i]<cnt且要进行第一个操作了,说明元素i要先进行更新在操作,更新也就是sum=sum-last+x,因为元素i被更新成last了,然后操作完后元素i又被更新成了x,且vis[i]=cnt表示该需要进行的第二个操作都进行完了,如果vis[i]==cnt且要进行第二个操作,那就没有必要鸟这些东西了,直接sum=sum-a[i]+x,a[i]=x;就可以;当进行操作2时,就需要更新,cnt++,sum=x*n,last=x;

#include<bits/stdc++.h>
#define ll long long
#define lowbit(i) ((-i)&(i))
using namespace std;
const ll inf=1e18;
const ll mod=1e8;
ll n,q,a[200005],sum,vis[200005];
int main(){
	//freopen("in.txt","r",stdin);
    scanf("%lld%lld",&n,&q);
    sum=0;
    ll cnt=0,last=0;
    for(int i=1;i<=n;i++) vis[i]=0;
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]),sum+=a[i];
    while(q--){
        ll t,i,x;
        scanf("%lld",&t);
        if(t==1){
            scanf("%lld%lld",&i,&x);
            if(vis[i]<cnt){
                sum=sum-last+x;
                vis[i]=cnt;
                a[i]=x;
            }
            else{
                sum=sum-a[i]+x;
                a[i]=x;
            }
            printf("%lld\n",sum);
        }
        else{
            scanf("%lld",&x);
            cnt++; last=x;
            sum=x*n;
            printf("%lld\n",sum);
        }
    }
	return 0;
}

C - Rooks Defenders

row[i]表示第i行车的数量,col[i]表示第i列车的数量,t1维护行的前缀和,t2维护列的前缀和,t1,t2为树状数组,查询的时候只要每行都满足至少有一个车或每列都满足至少有一个车就可以,放车的时候如果row[x]=1,就不需要修改t1了,反之需要修改,但无论修不修改都要row[x]++,col同理,删除的时候先让row[x]--,col[y]--,如果row[x]<=0才去修改,col同理,这样是为了保证查询前缀和的时候保证每行只有一个方便查询;

#include<bits/stdc++.h>
#define ll long long
#define lowbit(i) ((-i)&(i))
using namespace std;
const ll inf=1e18;
const ll mod=1e8;
ll n,q,t1[100005],t2[100005],row[100005],col[100005];
void add(ll flag,ll x,ll y){
    for(int i=x;i<=n;i+=lowbit(i))
        if(flag) t1[i]+=y;
        else t2[i]+=y;
}
ll ask(ll flag,ll x){
    ll res=0;
    for(int i=x;i;i-=lowbit(i))
        if(flag) res+=t1[i];
        else res+=t2[i];
    return res;
}
int main(){
	//freopen("in.txt","r",stdin);
	scanf("%lld%lld",&n,&q);
	while(q--){
        ll t,x,y,x1,y1;
        scanf("%lld",&t);
        if(t==1){
            scanf("%lld%lld",&x,&y);
            if(row[x]<1) add(1,x,1);
            if(col[y]<1) add(0,y,1);
            row[x]++;col[y]++;
        }
        else if(t==2){
            scanf("%lld%lld",&x,&y);
            row[x]--;col[y]--;
            if(row[x]<1) add(1,x,-1);
            if(col[y]<1) add(0,y,-1);
        }
        else{
            scanf("%lld%lld%lld%lld",&x,&y,&x1,&y1);
           // cout<<ask(1,x1)-ask(1,x-1)<<" ss "<<ask(0,y1)-ask(0,y-1)<<endl;
            if(ask(1,x1)-ask(1,x-1)>=x1-x+1||ask(0,y1)-ask(0,y-1)>=y1-y+1)
                printf("Yes\n");
            else printf("No\n");
        }
	}
	return 0;
}

pSort - 题目 - Daimayuan Online Judge

可以看出i能和|i-d[i]|,|i+d[i]|的位置互换,如果这两个绝对值都在[1,n]范围内的话,然后又可以发现这些可以可以互换的位置具有传递性,比如a和b可以换,b和c可以换,那a,b,c都可以换,所以只要找出这些连通块,看看b中这些交换的位置是否在一个连通块中就可以了,用并查集更方便;

#include<bits/stdc++.h>
#define ll long long
#define lowbit(i) ((-i)&(i))
using namespace std;
const ll inf=1e18;
const ll mod=1e8;
ll n,b[105],d[105],s[105];
ll findd(ll x){
    return s[x]=x==s[x]?x:findd(s[x]);
}
int main(){
	//freopen("in.txt","r",stdin);
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
        scanf("%lld",&b[i]);
        s[i]=i;
	}
	for(int i=1;i<=n;i++){
        scanf("%lld",&d[i]);
        if(i-d[i]>=1){
            ll j=i-d[i];
            ll u=findd(i),v=findd(j);
            if(u!=v) s[u]=v;
        }
        if(i+d[i]<=n){
            ll j=i+d[i];
            ll u=findd(i),v=findd(j);
            if(u!=v) s[u]=v;
        }
	}
	for(int i=1;i<=n;i++){
        if(findd(b[i])!=findd(i)){
               // cout<<findd(b[i])<<" "<<findd(i)<<" "<<i<<" "<<b[i]<<endl;
            printf("NO\n");
            return 0;
        }
	}
	printf("YES\n");
	return 0;
}

Candy Machine

可以看出删掉一个最大值,平均值会下降,那么我一开始全都要,然后从最大值开始删,每次统计有多少个大于平均值的,最后输出一个最大值就可以

#include<bits/stdc++.h>
#define ll long long
#define lowbit(i) ((-i)&(i))
using namespace std;
const ll inf=1e18;
const ll mod=1e8;
ll n,a[1000006];
int main(){
	//freopen("in.txt","r",stdin);
	scanf("%lld",&n);
	ll sum=0,ave=0,ans=0,cnt=0,ma=n;
	for(int i=1;i<=n;i++) scanf("%lld",&a[i]),sum+=a[i];
	sort(a+1,a+n+1);
	for(int i=n;i>=1;i--){
        ave=sum/i;
        while(a[ma]>ave) ma--,cnt++;
        ans=max(ans,cnt);
       // cout<<cnt<<" "<<i<<endl;
        sum-=a[i];
        cnt--;
	}
	printf("%lld\n",ans);
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
一个简单的盈利模型可以使用简单移动平均线(SMA)和价格的相对强弱指标(RSI)。在这里,我们使用5天的SMA和14天的RSI。 步骤1:计算5天的SMA 将前5天每日的收盘价加起来,除以5得到5天SMA。对于第6天以后的每一天,使用前5天的收盘价数据,将最后一个数据删掉,加上当天的收盘价,再除以5得到新的5天SMA。例如,第6天的SMA是(18.39 + 18.22 + 18.62 + 18.36 + 18.45)/ 5 = 18.48,第7天的SMA是(18.22 + 18.62 + 18.36 + 18.45 + 17.89)/ 5 = 18.11。 步骤2:计算14天的RSI 日价格变化的平均值为14天,其中日涨幅不为零的值与日跌幅不为零的值分别计算得到。每天的变化值为当天的收盘价减去前一天的收盘价的绝对值,如果涨了则记为正值,如果跌了则记为负值。然后计算14天涨幅的平均值和14天跌幅的平均值分别为U和D。计算RSI的公式为:RSI = 100 - (100 / (1 + U / D))。例如,第14天的U为(17.43 - 17.89)= 0.46,D为0,因为当天的收盘价较前一天下跌了。前14天的U和D可以使用同样的方法来计算。 步骤3:判断买入或卖出信号 当价格在5天SMA上方,并且RSI超过70时,表明股票处于超买状态,这时候可以考虑卖出;当价格在5天SMA下方,并且RSI低于30时,表明股票处于超卖状态,这时候可以考虑买入。 这是一个简单的数学模型,实际操作是复杂的,需要注意多个因素的综合考虑,并且需要进行风险管理。此处提供的仅为理论模型,仅供参考。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

killer_queen4804

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值