USACO S&G&P 题目选做
P8904 Mountains USACO22DEC G
感觉这题做法非常暴力。
对于一个楼房,我们钦定对于点 ,若 若符合题目条件,我们称作 看见 ,否则我们称作 看见 。
首先题目判断一个楼房是否能被看见是通过斜率来判断的,具体如下图。
然后我们考虑用一个set来维护每一个楼房能看见的所有楼房。
一开始把初始状态预处理出来。然后对于每一次修改 楼房的操作,显然先把 的高度加上应该加的。首先考虑能看到 的点,即 前面的点 。
我们枚举 的每一个点 ,找到 能看到的位置不超过 且最远的楼房 (这个点要么最高要么最矮),然后再判断连接 的直线的斜率与连接 的大小即可判断 是否能被 看见。
如果这个点不能被 看见,那这个点必然不会对 能看见的楼房数目产生影响。
但如果这个点能被 看见,那么我们需要枚举 后面所有能被 看见的点,判断斜率,直到有一个点 与 的斜率大于 的斜率(这样 必定不会对后面产生任何影响,因为此时 )。
最后我们再来处理 能看见的新的点,其实做法很暴力,我们直接每次清空 能看见的点,然后把仿照预处理把所有位置预处理一边即可。
#include<bits/stdc++.h> using namespace std; const int N=1e6+10; const int inf=1e9; int h[N],n,ans; set<int> s[N]; double getk(int i,int j){ return 1.0*(h[j]-h[i])/(j-i); } int main(){ // freopen("test.in","r",stdin); cin>>n;for(int i=1;i<=n;i++) cin>>h[i]; for(int i=1;i<=n;i++){ s[i].insert(0);s[i].insert(n+1); double tmp=-inf; for(int j=i+1;j<=n;j++){ if(tmp<=getk(i,j)){ // cout<<i<<" "<<j<<endl; tmp=getk(i,j);ans++;s[i].insert(j); } } } // cout<<ans<<endl; int T;cin>>T; while(T--){ int x,y;cin>>x>>y;h[x]+=y; for(int i=1;i<x;i++){ auto p=s[i].lower_bound(x);--p;int tmp=*p; if(tmp and getk(i,tmp)>getk(i,x)) continue; if(s[i].find(x)==s[i].end()){s[i].insert(x);ans++;}//如果以前i看不到x,现在i看得到x了 p=s[i].upper_bound(x);tmp=*p; while(tmp<=n){ if(getk(i,tmp)>=getk(i,x) and h[tmp]>=h[x]) break; s[i].erase(tmp);ans--;p=s[i].upper_bound(tmp);tmp=*p; } } ans-=s[x].size()-2; s[x].clear();s[x].insert(0);s[x].insert(n+1);double tmp=-inf; for(int j=x+1;j<=n;j++){ if(tmp<=getk(x,j)){ tmp=getk(x,j);ans++;s[x].insert(j); } } cout<<ans<<"\n"; } return 0; }
P2997 [USACO10NOV]Banner S
这个题有个显然结论,就是如果一条在网格中的直线不经过网格中除端点以外的其余点,那么这条直线对应的直角三角形的直角边必定互质,否则一定可以找到一个与其相似的直角三角形。
然后我们枚举两个直角边的长度,对于一组直角边 总共有 。
当然对于斜率为 ,即一组直角边中有一条边为 的边,我们不需要 。因为把它对称过来是一样的。做完了。
#include<bits/stdc++.h> using namespace std; #define int long long int n,m,l,r,ans; signed main(){ cin>>n>>m>>l>>r; for(int i=0;i<=n;i++){//直角边a的长度 for(int j=0;j<=m;j++){//直角边b的长度 if(i+j==0) continue; double tmp=sqrt(i*i+j*j); if(tmp>=l and tmp<=r){ if(__gcd(i,j)!=1) continue; if(i+j==1) ans+=(n-i+1)*(m-j+1); else ans+=2*(n-i+1)*(m-j+1); } } } cout<<ans; return 0; }```
本文作者:zplqwq
本文链接:https://www.cnblogs.com/zplqwq/p/17426922.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步