CSP-S2019 JX
注:使用了 IOI 赛制。
赛时:\(100+70+64+0+0=234\),目测上了 JX 1=。
补题:\(100+100+100+0+100=400\)。
T1
分数变动:\(73 \to 64 \to 73 \to 73 \to 100\)。
首先判定月份是否合法,若不合法则可以 保留个位 或者 把十位变成 \(1\)(\(73\) 分寄因:未考虑后者情况)。
如果合法,则保留原来的月份(\(64\) 分寄因:合法时没有保留原来月份)。
然后判断日期是否在上述两种情况其中一种的月份区间之内,若是则不用改日期,否则保留个位就行。
code
#include<bits/stdc++.h>
using namespace std;int m,d;
int m1,m2;
const int q[12][2]={{1,31},{1,28},{1,31},{1,30},{1,31},{1,30},{1,31},{1,31},{1,30},{1,31},{1,30},{1,31}};
char op;int main(){cin>>m>>op>>d;int ans=0;if(m<1||m>12){ans++;m1=m%10;m2=10+m%10;}elsem1=m2=m;if((d<q[m1-1][0]||d>q[m1-1][1])&&(d<q[m2-1][0]||d>q[m2-1][1]))ans++;cout<<ans;return 0;
}
总结:想题时,一定要将所有情况列出在草稿纸上,并多问自己是否全想到了。
涉及的知识点:分类讨论,模拟。
T2
分数变动:\(70\)。
\(70\) 分做法:令 \(sa_i=\sum_{j=1}^i a_j,sb_i=\sum_{j=1}^i b_j\),枚举每对 \((l,r)\),令 \(ans \leftarrow ans+(sa_r-sa_{l-1}) \times (sb_r-sb_{l-1})\) 即可。
考虑枚举其中右端点 \(r\),令 \(ans_r\) 表示以 \(r\) 为右端点的区间的贡献之和,则答案为 \(\sum_{i=1}^n ans_i\)。
接着推式子:
于是,我们在计算每个 \(ans_r\) 之后顺便维护 \(\sum_{l=0}^{r-1} sa_l,\sum_{l=0}^{r-1} sb_l,\sum_{l=0}^{r-1} sa_l \times sb_l\) 即可 \(O(1)\) 计算,总时间复杂度 \(O(n)\)。
code
#include<bits/stdc++.h>
#define int long long
using namespace std;const int N=5e5+5;
int n;
int ans[N];
int a[N],b[N];
int sa[N],sb[N];
const int MOD=1e9+7;signed main(){ios::sync_with_stdio(0);cin.tie(0);cin>>n;int ans1=0,ans2=0;for(int i=1;i<=n;i++){cin>>a[i];sa[i]=(sa[i-1]+a[i])%MOD;}for(int i=1;i<=n;i++){cin>>b[i];sb[i]=(sb[i-1]+b[i])%MOD;}int ssa=0,ssb=0,ssasb=0;for(int r=1;r<=n;r++){ans[r]=(((r%MOD*sa[r]%MOD*sb[r]%MOD-sa[r]%MOD*ssb%MOD+MOD)%MOD-sb[r]%MOD*ssa%MOD+MOD)%MOD+ssasb)%MOD;ssa=(ssa+sa[r])%MOD;ssb=(ssb+sb[r])%MOD;ssasb=(ssasb+sa[r]%MOD*sb[r]%MOD)%MOD;} int Ans=0;for(int i=1;i<=n;i++)Ans=(Ans+ans[i])%MOD;cout<<Ans;return 0;
}
总结:看到这种式子比较多的题,考虑推式子,推到将每个部分都可以直接计算或维护了为止。
涉及的知识点:数学。