首页 > 其他分享 >计蒜客掷标枪

计蒜客掷标枪

时间:2023-01-15 13:44:06浏览次数:28  
标签:pre ch int 掷标枪 链表 read 计蒜客 id

题目链接:https://www.jisuanke.com/problem/T3778

题目要求你根据公式依次算出每个人的掷标枪的距离然后计算得分,得分=离当前标枪落点最近后落点和前落点的标枪的距离之和

准确来说是这样的:

 

 让我们来计算得分;

这道题用暴力和set+二分都不行,6e6超了,后者的做法是o(nlogn)级别,只能过80%

正确的做法是双向链表维护(不得不说这道题真的给我好好上了一课)

参考代码:

 1 //因为xi = (ai%n) + 1 ≤ n,即1 ≤ xi ≤ 6 × 10^6,可是使⽤桶进⾏计数排序,然后建⽴有序的双向链表,
 2 //注意因为要找大于或小于的值,因此链表内重复的数字只加⼊⼀次。
 3 //题⽬求解的是依次加⼊xi时,计算结果之和,因为链表是通过计数排序建⽴的,
 4 //因此可以转变思路:从最后⼀个数开始逆序删除每个数,计算答案。
 5 //因为要删除,需要快速找到每个数在双向链表中位置,因此在建⽴双向链表的时候让xi位于索引xi处。
 6 //每次删除时,让桶中这个数字的次数减少1,当减少到0时,将该数从双向链表中删除。
 7 //总体的时间复杂度:O(n)
 8 
 9 #include<bits/stdc++.h>
10 using namespace std;
11 #define int long long
12 #define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);;
13 const int mod=1e9+7;
14 const int N=6e6+10;
15 int x[N],cnt[N];
16 int nxt[N],pre[N];
17 int n,B,A,C;
18 int a;
19 int tot,sum;
20 inline int read(){
21      int s=0,w=1;char ch=getchar();
22     while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
23     while(ch>='0'&&ch<='9')s=(s<<1)+(s<<3)+ch-'0',ch=getchar();
24     return s*w;
25 }
26 inline void write(int x)
27 {
28     if (x < 0) putchar('-'), x = -x;
29     if(x > 9)
30         write(x / 10);
31     putchar(x % 10 + '0');
32     return;
33 }
34 signed main()
35 {
36     IOS;
37     freopen("javelin.in", "r", stdin);
38     freopen("javelin.out", "w", stdout);
39     //n=read(),A=read(),B=read(),C=read(),a=read();
40     cin>>n>>A>>B>>C>>a;
41     x[1]=(a%n)+1;
42     cnt[x[1]]++;
43     for(int i=2;i<=n;i++)
44     {
45         a=(A*a%mod*a%mod+B*a%mod+C)%mod;
46         x[i]=(a%n)+1;
47         cnt[x[i]]++;
48     }
49     for(int i=0;i<N;i++)
50     {
51         if(cnt[i])
52         {
53             nxt[tot]=i;
54             pre[i]=tot;
55             tot=i;
56         }
57     }
58     nxt[tot]=N-9;
59     pre[N-9]=tot;;
60     for(int i=n;i>=1;i--)
61     {
62          int id=x[i];
63          if(nxt[id]!=N-9)
64          {
65              sum=(sum+nxt[id])%mod;
66          }
67          if(pre[id]!=0)
68          {
69              sum=(sum+pre[id])%mod;
70          }
71          cnt[id]--;
72          if(cnt[id]==0)
73          {
74              nxt[pre[id]]=nxt[id];
75              pre[nxt[id]]=pre[id];
76          }
77     }
78     cout<<sum<<endl;
79     return 0;
80 }

 

标签:pre,ch,int,掷标枪,链表,read,计蒜客,id
From: https://www.cnblogs.com/LQS-blog/p/17053378.html

相关文章

  • 计蒜客 - T2144 拼数
    计蒜客-T2144拼数题解:把所有数字看成字符串,但是难道直接降序排就结束了嘛,不是的,我们来看一个反例:31312虽然312>31但是明显31312>31231,所以我们不能简单的排序,我......
  • 计蒜客 剪刀石头布
    题目:初始代码#include<stdio.h>intmain(){intN,NA[200],NB[200];intna,nb;intsuma=0,sumb=0;scanf("%d%d%d",&N,&na,&nb);for(inti=0;......
  • 计蒜客 | 矩阵蛇形输出
    题目:给定一个m行、n*列的矩阵,请按照下图所示的顺序输出矩阵中所有的元素(从[0][0]位置开始,具体请参见下图)。注意每次碰到边界后,必须且只能沿着边界移动一格,不能后退......